OpenCV Error: Assertion failed (scn == 3 || scn == 4)
in cv::cvtColor, file C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp, line 11111
1 加载路径有错误
2 参数0是灰度,再灰度化出错
模板匹配
import cv2
import numpy as np
#加载原始RGB图像
img_rgb = cv2.imread("C:/Users/AEC/Desktop/1.png")
#创建一个原始图像的灰度版本,所有操作在灰度版本中处理,然后在RGB图像中使用相同坐标还原
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
#加载将要搜索的图像模板
template = cv2.imread('C:/Users/AEC/Desktop/2.png',0)
#记录图像模板的尺寸
w, h = template.shape[::-1]
"""
#查看三组图像(图像标签名称,文件名称)
cv2.namedWindow("rgb")
cv2.imshow('rgb',img_rgb)
cv2.namedWindow("gray")
cv2.imshow('gray',img_gray)
cv2.namedWindow("template")
cv2.imshow('template',template)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""
#使用matchTemplate对原始灰度图像和图像模板进行匹配
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
#设定阈值
threshold = 0.7
#res大于70%
loc = np.where( res >= threshold)
#使用灰度图像中的坐标对原始RGB图像进行标记
for pt in zip(*loc[::-1]):
cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
#显示图像
cv2.namedWindow("Detected",0)
cv2.imshow('Detected',img_rgb)
cv2.imwrite("1_after.png",img_rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()
模板
问题1 如果图像旋转了就匹配不到,试着解决这个问题 解决方案:
旋转模板匹配图案
问题2 可以看到对同一个图有多个框标定,需要去重,只需要保留一个
解决方案:对框边界值设置阈值,阈值范围内就当成一个框
问题3 可能有漏检过检情况
通过调节阈值解决
经过差不多大半天的努力解决了以上一些问题
下面这个程序实现对两个图案的匹配
import cv2
import numpy as np
# 加载原始RGB图像
img_rgb = cv2.imread("origin.png")
# 创建一个原始图像的灰度版本,所有操作在灰度版本中处理,然后在RGB图像中使用相同坐标还原
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
# 加载将要搜索的图像模板
#模板1 筛选图案1
template1 = cv2.imread('template1.png', 0)
#模板2 3 筛选图案2
template2 = cv2.imread('template2.png', 0)
template3 = cv2.imread('template3.png', 0)
# 记录图像模板的尺寸
w1, h1 = template1.shape[::-1]
w2, h2 = template2.shape[::-1]
w3, h3 = template3.shape[::-1]
def rotate_bound(image, angle):#图片旋转但不改变大小,模板匹配中大小改变对匹配效果有影响
(h, w) = image.shape[:2]
(cX, cY) = (w // 2, h // 2)#//是向下取整
M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY
return cv2.warpAffine(image, M, (nW, nH))
#选出所有匹配旋转模板且不重复的图案
def make_contour(template,w,h,angle,threshold):
rects = []
# 模板旋转匹配
for i in range(0, 360, angle):
new_rotate = rotate_bound(template, i)
# 把图片旋转后黑色的部分填充成白色
new_rotate[new_rotate == 0] = 255
# 使用matchTemplate对原始灰度图像和图像模板进行匹配
res = cv2.matchTemplate(img_gray, new_rotate, cv2.TM_CCOEFF_NORMED)
# 设定阈值
loc = np.where(res >= threshold)
#x,y坐标对调打包
for pt in zip(*loc[::-1]):
point = np.array([[pt[0], pt[1]], [pt[0] + w, pt[1]],
[pt[0], pt[1] + h], [pt[0] + w, pt[1] + h]])
rects.append(cv2.boundingRect(point))
#模板匹配后符合要求的所有图案数量
length = len(rects)
#设定阈值
threshold = 3
i = 0
#如果两个图案距离在阈值范围内,则等同,然后用集合去重
while(i