记录一次使用python调用cv2批处理图片添加边框
模板匹配法,canny边缘检测算法。
先检测原图片是否有框,原图有框再加就重复了。
思路:windows界面下右上角的关闭按钮X是必有的。所以检测右上角是否有X
检测右上角是否有“X”形状的关闭按钮。
image_path: 输入图片路径
region_size: 要检测的区域大小
return: 如果有“X”形状的关闭按钮,返回True,否则返回False
使用cv2读取灰度图像
截取图片右上角50x50px(目的是减少整张图特征识别时候干扰), 注意,图像坐标原点一般位于图像的左上角
然后用原图片的尺寸,x,y减去像素区域即可。
定义剪裁区域:
top_left_x = width - 100 top_left_y = 0 bottom_right_x = width bottom_right_y = 100
使用canny边缘检测算法处理图片,方便做右上角X的特征识别。
这里2种方案可以给出X模板图像,也可以不给。
1.不给
不给的话 就提取轮廓的面积和外界矩形的左上角坐标以及长宽
判断外接矩形的宽高比是否在 0.8 到 1.2 之间。(X的主要特征)
if area > 100 and w > 10 and h > 10 and 0.8 < w / h < 1.2: return True
2.给出模板图像
使用边缘检测处理模板图像,然后获取模板图像的w和h
在0.2-1.5之间生成30个数字。
用这些数字去乘以图像的w和h得到不同尺寸的模板图像。
然后使用模板匹配法去匹配,并且得到匹配结果。记录最大值
# 进行模板匹配
res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF, mask=mask)
它能够在输入图像中搜索并找到与给定模板图像最匹配的位置。
因为用了Canny边缘检测处理,所以都是线条之间的匹配。
method: 匹配方法,用于指定模板匹配的算法。可选的方法包括:
cv2.TM_SQDIFF: 平方差匹配法,最小值表示最好的匹配。
cv2.TM_SQDIFF_NORMED: 归一化平方差匹配法,值范围在0到1,最小值表示最好的匹配。
cv2.TM_CCORR: 相关性匹配法,最大值表示最好的匹配。
cv2.TM_CCORR_NORMED: 归一化相关性匹配法,值范围在0到1,最大值表示最好的匹配。
cv2.TM_CCOEFF: 相关系数匹配法,最大值表示最好的匹配。
cv2.TM_CCOEFF_NORMED: 归一化相关系数匹配法,值范围在-1到1,最大值表示最好的匹配。
区别和适用场景:
平方差匹配 (cv2.TM_SQDIFF 和 cv2.TM_SQDIFF_NORMED): 适用于需要精确位置匹配和像素级别匹配的情况,例如物体定位。
相关性匹配 (cv2.TM_CCORR 和 cv2.TM_CCORR_NORMED): 适用于灰度信息一致的情况,可以用于找出相似模式的多个实例,但对光照变化敏感。
相关系数匹配 (cv2.TM_CCOEFF 和 cv2.TM_CCOEFF_NORMED): 适用于光照和对比度变化较大的场景,通常用于图像识别和对象检测。
res是一个元组类型,可以用cv2给出的cv2.minMaxLoc(result)拆包
根据设置的相似度阈值去对比匹配结果。检查找到的匹配区域是否大于阈值(我这里的阈值是0.8
最后返回一个bool值。
# 设定阈值 threshold = 0.8 # 检查是否找到了匹配的区域并且匹配值大于阈值 if found and found[0] >= threshold: return True else: return False
检测方法写完以后 就是加框了
边框随便截一张Windows下的应用程序把内部掏空就好了。
调整变宽的尺寸略大于原图像。
frame_width = int(image_width * 1.00)
frame_height = int(image_height * 1.05)
resized_frame = frame.resize((frame_width, frame_height), Image.LANCZOS)
然后就是图片的左上角坐标,在框架的居中位置的坐标应该是多少:
position = (
(frame_width - new_image_width) // 2,
(frame_height - new_image_height) // 2
)
可以在这里适当添加偏移量,保证自己想要的效果实现
然后就是创建一个新的图像,先将边框粘贴到新图像上面,然后paste图像到边框中间上就好了。
这里比较简单,第一次做就是容易搞不清坐标原点在图像的左上角。
最后保存,结束。
canny主要步骤:
1.噪声抑制:
首先,通过使用高斯滤波器对图像进行平滑处理,以去除图像中的噪声。高斯滤波器可以有效地平滑图像,同时保持边缘的细节。
2.计算梯度幅值和方向:
使用Sobel算子计算图像中每个像素点的水平和垂直方向的梯度值。然后,根据梯度值计算每个像素点的梯度幅值和方向。
3.非极大值抑制:
在计算得到的梯度幅值图像上进行非极大值抑制。这一步的目的是将边缘宽度变窄,使得边缘更加细化和明确。
4.双阈值处理:
根据设定的高阈值和低阈值,将梯度幅值图像中的像素点分为强边缘、弱边缘和非边缘三类。通常选择高阈值和低阈值使得强边缘像素点的梯度幅值大于高阈值,非边缘像素点的梯度幅值小于低阈值,而弱边缘像素点的梯度幅值处于高阈值和低阈值之间。
5.边缘连接:
最后,通过连接强边缘像素点和与之相邻的弱边缘像素点,得到完整的边缘图像。