失败笔记本-HALCON篇-007
项目场景:
今天来研究一下keyence的小例子,轮廓平滑:
参考链接:【例1 轮廓平滑化】膨胀n次+收缩n次
- 想要实现的是如下效果:
1.HALCON实现思路
步骤:
其实在使用halcon实现的过程中,遇到了一些困难:先使用dilation算子做膨胀,后erosion算子做腐蚀,很难调出想要的效果,按照之前学习的思路,想要去除轮廓上的毛刺,可以使用开运算,但是开运算的化是先腐蚀后膨胀。按照先腐蚀后膨胀的思路代码如下:
read_image (Image, 'D:/WORKSPACE/HALCON/轮廓平滑化/001.png')
rgb1_to_gray (Image, GrayImage)
threshold (GrayImage, Regions, 10, 171)
erosion_circle (Regions, RegionErosion, 3.5)
dilation_circle (RegionErosion, RegionDilation, 4)
erosion_circle (RegionErosion, RegionErosion1, 3.5)
dilation_circle (RegionErosion1, RegionDilation1, 4)
erosion_circle (RegionErosion1, RegionErosion2, 3.5)
dilation_circle (RegionErosion2, RegionDilation2, 4)
erosion_circle (RegionErosion2, RegionErosion3, 3.5)
dilation_circle (RegionErosion3, RegionDilation3, 8)
dilation_circle (RegionDilation3, RegionDilation4, 4.7)
difference (Regions, RegionDilation4, RegionDifference)
connection (RegionDifference, ConnectedRegions)
select_obj (ConnectedRegions, ObjectSelected, 2)
difference (Regions, ObjectSelected, RegionDifference1)
reduce_domain (Image, RegionDifference1, ImageReduced)
效果如下:

这里还是做了一下select和做差的,要选择出需要裁剪的region,然后再求差求出所保留的region。
1.换个实现思路
步骤:
仔细阅读了keyence的例子说明,发现keyence的膨胀处理原理是选择3*3的数据中像素值最大的放在中心,如下:
收缩也是如此,是选择最小值放在中间,这就需要额外的处理了:在python中实现一下:
from PIL import Image
import numpy as np
def max_filter(image):
# 将图像转换为灰度图像
# gray_image = image.convert('L')
# 将灰度图像转换为numpy数组
img_array = np.array(image)
# 获取图像的宽和高
height, width = img_array.shape
# 在图像边界周围添加一圈零填充
padded_img = np.pad(img_array, pad_width=1, mode='constant', constant_values=0)
# 创建一个新的数组来存储处理后的图像
new_img_array = np.copy(img_array)
# 遍历每一个像素(包括边界像素)
for i in range(height):
for j in range(width):
# 获取3×3窗口中的像素值
window = padded_img[i:i+3, j:j+3]
# 找到窗口中的最大值
max_value = np.max(window)
# 将中心像素值替换为最大值
new_img_array[i, j] = max_value
# 将处理后的数组转换回图像
new_image = Image.fromarray(new_img_array)
return new_image
上面是膨胀的函数,收缩也是类似的,使用这个新的函数处理图片结果如下:
从左到右分别是膨胀收缩3次,4次,5次的结果,确实有效果啊,厉害厉害。
但是还是有一个小尖尖,这个暂时不知道是什么原因,可能是函数处理有问题,求大佬们的支援。
完整代码如下:
from PIL import Image
import numpy as np
def max_filter(image):
# 将图像转换为灰度图像
# gray_image = image.convert('L')
# 将灰度图像转换为numpy数组
img_array = np.array(image)
# 获取图像的宽和高
height, width = img_array.shape
# 在图像边界周围添加一圈零填充
padded_img = np.pad(img_array, pad_width=1, mode='constant', constant_values=0)
# 创建一个新的数组来存储处理后的图像
new_img_array = np.copy(img_array)
# 遍历每一个像素(包括边界像素)
for i in range(height):
for j in range(width):
# 获取3×3窗口中的像素值
window = padded_img[i:i+3, j:j+3]
# 找到窗口中的最大值
max_value = np.max(window)
# 将中心像素值替换为最大值
new_img_array[i, j] = max_value
# 将处理后的数组转换回图像
new_image = Image.fromarray(new_img_array)
return new_image
def min_filter(image):
# 将图像转换为灰度图像
# gray_image = image.convert('L')
# 将灰度图像转换为numpy数组
img_array = np.array(image)
# 获取图像的宽和高
height, width = img_array.shape
# 在图像边界周围添加一圈零填充
padded_img = np.pad(img_array, pad_width=1, mode='constant', constant_values=0)
# 创建一个新的数组来存储处理后的图像
new_img_array = np.copy(img_array)
# 遍历每一个像素(不包括边界像素)
for i in range(1, height-1):
for j in range(1, width-1):
# 获取3×3窗口中的像素值
window = padded_img[i:i+3, j:j+3]
# 找到窗口中的最大值
min_value = np.min(window)
# 将中心像素值替换为最大值
new_img_array[i, j] = min_value
# 将处理后的数组转换回图像
new_image = Image.fromarray(new_img_array)
return new_image
# 打开图像文件
image = Image.open('001.png')
gray_image = image.convert('L')
# 应用最大值过滤器
processed_image = max_filter(gray_image)
processed_image1 = max_filter(processed_image)
processed_image2 = max_filter(processed_image1)
processed_image3 = max_filter(processed_image2)
processed_image4 = max_filter(processed_image3)
processed_image5 = max_filter(processed_image4)
processed_image6 = max_filter(processed_image5)
processed_image7 = max_filter(processed_image6)
min_image = min_filter(processed_image3)
min_image1 = min_filter(min_image)
min_image2 = min_filter(min_image1)
min_image3 = min_filter(min_image2)
min_image4 = min_filter(min_image3)
min_image5 = min_filter(min_image4)
min_image6 = min_filter(min_image5)
min_image7 = min_filter(min_image6)
# 保存处理后的图像
min_image3.save('min_image3.jpg')
总结:
在007中,用到了keyence的图像处理思路,了解了其膨胀和收缩的原理和应用。