2026/2/22 0:39:03
网站建设
项目流程
上海网站制作策,工信部网站备案信息查询,阿里云网站域名绑定,WordPress 建电商网站纯手打持续更新中~1、轮廓检测#xff08;findContours#xff09;cv2.findContours(img,mode,method)mode:轮廓检索模式RETR_EXTERNAL #xff1a;只检索最外面的轮廓#xff1b;RETR_LIST#xff1a;检索所有的轮廓#xff0c;并将其保存到一条链表当中#xff1b;RET…纯手打持续更新中~1、轮廓检测findContourscv2.findContours(img,mode,method)mode:轮廓检索模式RETR_EXTERNAL 只检索最外面的轮廓RETR_LIST检索所有的轮廓并将其保存到一条链表当中RETR_CCOMP检索所有的轮廓并将他们组织为两层顶层是各部分的外部边界第二层是空洞的边界;RETR_TREE检索所有的轮廓并重构嵌套轮廓的整个层次;最常用这个method:轮廓逼近方法CHAIN_APPROX_NONE以Freeman链码的方式输出轮廓所有其他方法输出多边形顶点的序列。CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分也就是函数只保留他们的终点部分。输入图像的要求必须是二值的更高的准确率img cv2.imread(contours.png) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 这一步对图像二值处理 cv_show(thresh,thresh)binary, contours, hierarchy cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)binary 为二值化之后的结果contours为轮廓信息hierarchy 表示层级绘制轮廓drawContours#传入绘制图像轮廓轮廓索引颜色模式线条厚度 # 注意需要copy,要不原图会变。。。 draw_img img.copy() res cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2) cv_show(res,res)draw_img img.copy() res cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2) cv_show(res,res)轮廓特征与近似contourArea轮廓特征计算cnt contours[0] #面积 cv2.contourArea(cnt) #周长True表示闭合的 cv2.arcLength(cnt,True)轮廓近似img cv2.imread(contours2.png) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) binary, contours, hierarchy cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) cnt contours[0] draw_img img.copy() res cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2) cv_show(res,res)这里用到了近似函数approxPolyDPepsilon 0.15*cv2.arcLength(cnt,True) # 0.15 越小是越貼合的 approx cv2.approxPolyDP(cnt,epsilon,True) #cnt是轮廓epsilon是指定需要比较的值一般是周长的倍数 draw_img img.copy() res cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2) cv_show(res,res)2、模板匹配matchTemplate两张图片现在是要看第一张图片是在第二张图片的哪一个部分。把右边的图片分成九宫格然后opencv会从左到右从上到下进行一点点的匹配逐像素匹配像素点的差异看看左边的图像是在右边的哪个位置。模板匹配和卷积原理很像模板在原图像上从原点开始滑动计算模板与图像被模板覆盖的地方的差别程度这个差别程度的计算方法在opencv里有6种然后将每次计算的结果放入一个矩阵里作为结果输出。假如原图形是AxB大小而模板是axb大小则输出结果的矩阵是(A-a1)x(B-b1)模板匹配的代码代码在notebook中运行# 模板匹配 img cv2.imread(lena.jpg, 0) template cv2.imread(face.jpg, 0) h, w template.shape[:2] img.shape # 输出(263, 263) template.shape # 输出(110, 85)有以下6种差异计算方法TM_SQDIFF计算平方不同计算出来的值越小越相关TM_CCORR计算相关性计算出来的值越大越相关TM_CCOEFF计算相关系数计算出来的值越大越相关TM_SQDIFF_NORMED计算归一化平方不同计算出来的值越接近0越相关推荐用归一化的结果会更可靠一些。TM_CCORR_NORMED计算归一化相关性计算出来的值越接近1越相关TM_CCOEFF_NORMED计算归一化相关系数计算出来的值越接近1越相关公式https://docs.opencv.org/3.3.1/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695dmethods [cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]cv2.minMaxLoc()是专门用于提取匹配结果矩阵res中极值最小值 / 最大值及对应坐标的核心函数.最小值就是根据需要匹配的图中找到原图中的一个匹配点后续根据h和w就能画出一个候选的方框。res cv2.matchTemplate(img, template, cv2.TM_SQDIFF) res.shape # (154, 179) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(res) # min_val:39168.0 max_val:74403584.0 min_loc:(107, 89) max_loc:(159, 62)for meth in methods: img2 img.copy() # 匹配方法的真值 method eval(meth) print (method) res cv2.matchTemplate(img, template, method) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(res) # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED取最小值 if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: top_left min_loc else: top_left max_loc bottom_right (top_left[0] w, top_left[1] h) # 画矩形 cv2.rectangle(img2, top_left, bottom_right, 255, 2) plt.subplot(121), plt.imshow(res, cmapgray) plt.xticks([]), plt.yticks([]) # 隐藏坐标轴 plt.subplot(122), plt.imshow(img2, cmapgray) plt.xticks([]), plt.yticks([]) plt.suptitle(meth) plt.show()示例如果是匹配多个对象img_rgb cv2.imread(mario.jpg) img_gray cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template cv2.imread(mario_coin.jpg, 0) h, w template.shape[:2] res cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) threshold 0.8 # 取匹配程度大于%80的坐标 loc np.where(res threshold) for pt in zip(*loc[::-1]): # *号表示可选参数 bottom_right (pt[0] w, pt[1] h) cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2) cv2.imshow(img_rgb, img_rgb) cv2.waitKey(0)3、图像金字塔pyrUppyrDown把图像组合成金字塔的形状可以用于图像特征提取每层的特征提取的结果组合在一起。高斯金字塔向下采样方法缩小用高斯核然后把偶数列全部去掉。高斯金字塔向上采样方法放大用相同的卷积核来卷积可以想象10这个像素平均的分给了周围的像素点。代码实验imgcv2.imread(AM.png) cv_show(img,img) print (img.shape) # (442, 340, 3)# 上采样 upcv2.pyrUp(img) cv_show(up,up) print (up.shape) #(884, 680, 3)#下采样方法 downcv2.pyrDown(img) cv_show(down,down) print (down.shape) # (221, 170, 3)拉普拉斯金字塔拉普拉斯金字塔的每一层 当前层的高斯图像 - 上采样后的下一层高斯图像。downcv2.pyrDown(img) down_upcv2.pyrUp(down) l_1img-down_up cv_show(l_1,l_1)