OpenCV-计算机视觉技术林伟鹏版第四章图像轮廓检测文章目录OpenCV-计算机视觉技术林伟鹏版前言一、图像轮廓检测概念1.概念二、图像轮廓检测1.图像二值化转换2.图像轮廓匹配3.二值图轮换轮廓检测4.图像轮廓检测凸包5.多边形轮廓检测前言本博客将教会大家如何使用opencv做一些基础内容一、图像轮廓检测概念1.概念二、图像轮廓检测1.图像二值化转换代码如下环境需要opencv,在jupyter中运行参考之前文章概念了解#二值图转换 import cv2 imgcv2.imread(1.png)imgraycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#将图像由BGR彩色转化为灰度图像 _,threshcv2.threshold(imgray,127,225,cv2.THRESH_TOZERO)cv2.imshow(threshold,thresh)cv2.waitKey()其中threshold有多种不同方式进行阈值二值化处理如下图所示2.图像轮廓匹配代码如下环境需要opencv,在jupyter中运行参考之前文章概念了解计算方式#轮廓匹配 能使用颜色标注出我们给定的轮廓importcv2 notation_imagecv2.imread(4.png,cv2.IMREAD_COLOR)notation_map_imagecv2.imread(5.png,cv2.IMREAD_COLOR)#下面将图像进行灰度处理notation_graycv2.cvtColor(notation_image,cv2.COLOR_BGR2GRAY)notation_map_graycv2.cvtColor(notation_map_image,cv2.COLOR_BGR2GRAY)#将灰度处理的图像进行二值化处理_,notation_thresholdcv2.threshold(notation_gray,130,255,cv2.THRESH_BINARY)_,notation_map_thresholdcv2.threshold(notation_map_gray,130,255,cv2.THRESH_BINARY)notation_contours,_cv2.findContours(notation_threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)notation_map_contours,_cv2.findContours(notation_map_threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#设置轮廓匹配阈值thres2.0foriinrange(len(notation_map_contours)):retvalcv2.matchShapes(notation_contours[0],notation_map_contours[i],cv2.CONTOURS_MATCH_I3,0.0)#notation_contours[0]表示对比的目标轮廓点集1也就是我们要匹配的轮廓我们要找张这样的轮廓#notation_map_contours[i] 表示对比的目标轮廓点集2也是我们要在这里面找和我们匹配的轮廓#第三个参数表示轮廓的比较方式方式分为三种分别为cv2.CONTOURS_MATCH_I1cv2.CONTOURS_MATCH_I2# cv2.CONTOURS_MATCH_I3。这三种方式都是对轮廓的Hu矩进行差异运算# Hu矩可以理解为轮廓的基本属性其具有平移、旋转和尺度不变性的图像特征#匹配轮廓ifretvalthres:#判断匹配后的阈值是否与我们设置的初始阈值大小关系#匹配成功将匹配上图像进(255,255,0)颜色标注print(index:%d retval: %f if is matched%(i,retval))cv2.drawContours(notation_map_image,notation_map_contours,i,(255,255,0),2)else:#匹配失败将匹配失败图像使用(0,0,255) 红色进行标注print(index:%d retval: %f if is not matched%(i,retval))cv2.drawContours(notation_map_image,notation_map_contours,i,(0,0,255),2)cv2.imshow(matched,notation_map_image)cv2.waitKey()3.二值图轮换轮廓检测代码如下环境需要opencv,在jupyter中运行参考之前文章概念了解计算方式#二值图转换轮廓检测importcv2importnumpyasnpimportrandom#本例中无须使用回调函数故回调函数为空defonChange(x):pass#使用imread 读取图片默认加载彩色的imgcv2.imread(1.jpg,cv2.IMREAD_COLOR)#将彩色图像使用cvtColor函数转化为 gray灰度图像graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#我们使用高斯滤波进行处理一下 使用的 3,3 标准核大小blurcv2.GaussianBlur(gray,(3,3),0)# 创建一个名字为findContours的窗口cv2.namedWindow(findContours)#创建一个 滑动条 滑动条的值域范围 是 20,255滑动条的名称为threshold#滑动条在什么地方呢滑动条在我们这个findContours窗口上cv2.createTrackbar(threshold,findContourschuangk,20,s255,onChange)#整体while循环这个循环作用# 让我们大家可以直观的感受到我们调整了滑动条设置域值变化对图像影响while(True):#创建一个 全一矩阵black255*np.ones(dtypenp.uint8,shapeimg.shape)#获取我们滑动条的 上面显示的数值将这个数值传给我们的thresthrescv2.getTrackbarPos(threshold,findContours)#进行我们的二值图转换#gray 是输入灰度图像要处理的图像#thres 我们滑动条控制的域值#255 表示我们的最大值 就是 二值图 的像素如果超过了thres就变成255#THRESH_BINARY二值话类型的 方法 表示超过阈值设为最大值否则为0。_,edgescv2.threshold(gray,thres,255,cv2.THRESH_BINARY)#轮廓检测#edges 表示我们输入的 二值化处理后的图像#cv2.RETR_TREE 表示我们检测轮廓的模式 检测所有轮廓建立完整的层级关系# 表示我们计算轮廓的近似方法使用的是这个方法contours,_cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#绘制轮廓图#drawContours 中的 black表示 我们要绘制的图像foriinrange(len(contours)):color(random.randint(0,255),random.randint(0,255),random.randint(0,255))cv2.drawContours(black,contours,i,color,2)#轮廓绘制cv2.imshow(findContours,img)cv2.imshow(Contours,black)ifcv2.waitKey(100)27:break颜色随机展示4.图像轮廓检测凸包代码如下环境需要opencv,在jupyter中运行参考之前文章概念了解#多边形轮廓检测importcv2importnumpyasnpimportrandom#回调函数本例中无须使用故为空defonChange(x):passimgcv2.imread(4.jfif,cv2.IMREAD_COLOR)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)blurcv2.GaussianBlur(gray,(15,15),0)cv2.namedWindow(polygonContours)cv2.createTrackbar(epsilon,polygonContours,10,200,onChange)cv2.createTrackbar(threshold,polygonContours,120,255,onChange)while(True):epsiloncv2.getTrackbarPos(epsilon,polygonContours)threscv2.getTrackbarPos(threshold,polygonContours)_,threshcv2.threshold(blur,thres,255,cv2.THRESH_BINARY)contours,hiercv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)frameimg.copy()forcincontours:#对轮廓进行多边形逼近approxcv2.approxPolyDP(c,epsilon,True)cv2.drawContours(frame,[approx],-1,(255,0,255),2)#检测图形边界框并绘制x,y,w,hcv2.boundingRect(approx)cv2.rectangle(frame,(x,y),(xw,yh),(0,255,0),3)#检测最小封闭区间(矩形并绘制rectcv2.minAreaRect(approx)boxcv2.boxPoints(rect)boxnp.intp(box)cv2.drawContours(frame,[box],0,(0,0,255),3)#检测最小封闭区间圆形并绘制(x,y),radiuscv2.minEnclosingCircle(approx)center(int(x),int(y))radiusint(radius)cv2.circle(frame,center,radius,(255,0,0),2)#轮廓绘制cv2.imshow(polygonContours,frame)ifcv2.waitKey(100)27:break5.多边形轮廓检测#多边形轮廓检测importcv2importnumpyasnpimportrandom#回调函数本例中无须使用故为空defonChange(x):pass#imread读取图像 cv2.IMREAD_COLOR读取彩色图像imgcv2.imread(4.jfif,cv2.IMREAD_COLOR)#将彩色图像转化为灰度图像graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#进行高斯滤波处理blurcv2.GaussianBlur(gray,(15,15),0)#创建一个窗口名字为polygonContourscv2.namedWindow(polygonContours)#创建两个滑动条 一个叫 epsilon 一个叫threshold 两个都在上述这个窗口中cv2.createTrackbar(epsilon,polygonContours,10,200,onChange)cv2.createTrackbar(threshold,polygonContours,120,255,onChange)while(True):#epsilon和这个thres是分别获取两个滑动条的值epsiloncv2.getTrackbarPos(epsilon,polygonContours)threscv2.getTrackbarPos(threshold,polygonContours)#这里就根据我们要二值处理的 rhres这个参数传入进行二值处理作为判断的阈值_,threshcv2.threshold(blur,thres,255,cv2.THRESH_BINARY)#寻找轮廓处理contours,hiercv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)frameimg.copy()forcincontours:#对轮廓进行多边形逼近#approxPolyDP#第一个表示我们输出轮廓的 点集#第二个参数表示 逼近精度 值越小 表面逼近精度越精确值越大表面轮廓越简化#true 表示多边形是闭合的approxcv2.approxPolyDP(c,epsilon,True)#表示绘制我们多边形逼近结果cv2.drawContours(frame,[approx],-1,(255,0,255),2)#检测图形边界框并绘制#boundingRect 绘制我们的矩形外框 绿色x,y,w,hcv2.boundingRect(approx)cv2.rectangle(frame,(x,y),(xw,yh),(0,255,0),3)#检测最小封闭区间(矩形并绘制#minAreaRect 绘制最小外接矩阵红色rectcv2.minAreaRect(approx)boxcv2.boxPoints(rect)boxnp.intp(box)cv2.drawContours(frame,[box],0,(0,0,255),3)#检测最小封闭区间圆形并绘制#minEnclosingCircle 绘制最小外接圆蓝色(x,y),radiuscv2.minEnclosingCircle(approx)center(int(x),int(y))radiusint(radius)cv2.circle(frame,center,radius,(255,0,0),2)#轮廓绘制cv2.imshow(polygonContours,frame)ifcv2.waitKey(100)27:break在这里插入图片描述