OpenCV-计算机视觉技术(林伟鹏版)
第四章:图像轮廓检测
文章目录
- OpenCV-计算机视觉技术(林伟鹏版)
- 前言
- 一、图像轮廓检测概念
- 1.概念
- 二、图像轮廓检测
- 1.图像二值化转换
- 2.图像轮廓匹配
- 3.二值图轮换轮廓检测
- 4.图像轮廓检测凸包
- 5.多边形轮廓检测
前言
本博客将教会大家如何使用opencv做一些基础内容
一、图像轮廓检测概念
1.概念
二、图像轮廓检测
1.图像二值化转换
代码如下(环境需要opencv,在jupyter中运行,参考之前文章):
- 概念了解:
#二值图转换 import cv2 img=cv2.imread('1.png')imgray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#将图像由BGR彩色转化为灰度图像 _,thresh=cv2.threshold(imgray,127,225,cv2.THRESH_TOZERO)cv2.imshow('threshold',thresh)cv2.waitKey()- 其中threshold有多种不同方式进行阈值二值化处理,如下图所示
2.图像轮廓匹配
代码如下(环境需要opencv,在jupyter中运行,参考之前文章):
概念了解:
计算方式:
#轮廓匹配 能使用颜色标注出我们给定的轮廓importcv2 notation_image=cv2.imread('4.png',cv2.IMREAD_COLOR)notation_map_image=cv2.imread('5.png',cv2.IMREAD_COLOR)#下面将图像进行灰度处理notation_gray=cv2.cvtColor(notation_image,cv2.COLOR_BGR2GRAY)notation_map_gray=cv2.cvtColor(notation_map_image,cv2.COLOR_BGR2GRAY)#将灰度处理的图像进行二值化处理_,notation_threshold=cv2.threshold(notation_gray,130,255,cv2.THRESH_BINARY)_,notation_map_threshold=cv2.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)#设置轮廓匹配阈值thres=2.0foriinrange(len(notation_map_contours)):retval=cv2.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_I1,cv2.CONTOURS_MATCH_I2,# cv2.CONTOURS_MATCH_I3。这三种方式都是对轮廓的Hu矩进行差异运算,# Hu矩可以理解为轮廓的基本属性,其具有平移、旋转和尺度不变性的图像特征#匹配轮廓ifretval<thres:#判断匹配后的阈值是否与我们设置的初始阈值大小关系#匹配成功,将匹配上图像进(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 读取图片,默认加载彩色的,img=cv2.imread('1.jpg',cv2.IMREAD_COLOR)#将彩色图像使用cvtColor函数转化为 gray灰度图像gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#我们使用高斯滤波进行处理一下 使用的 3,3 标准核大小blur=cv2.GaussianBlur(gray,(3,3),0)# 创建一个名字为findContours的窗口cv2.namedWindow('findContours')#创建一个 滑动条 滑动条的值域范围 是 20,255,滑动条的名称为threshold#滑动条在什么地方呢,滑动条在我们这个findContours窗口上cv2.createTrackbar('threshold','findContourschuangk',20,s255,onChange)#整体while循环,这个循环作用,# 让我们大家可以直观的感受到我们调整了滑动条设置域值变化对图像影响while(True):#创建一个 全一矩阵black=255*np.ones(dtype=np.uint8,shape=img.shape)#获取我们滑动条的 上面显示的数值,将这个数值传给我们的thresthres=cv2.getTrackbarPos('threshold','findContours')#进行我们的二值图转换#gray 是输入灰度图像,要处理的图像#thres 我们滑动条控制的域值#255 表示我们的最大值, 就是 二值图 的像素如果超过了thres就变成255#THRESH_BINARY二值话类型的 方法 表示超过阈值设为最大值,否则为0。_,edges=cv2.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):passimg=cv2.imread('4.jfif',cv2.IMREAD_COLOR)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)blur=cv2.GaussianBlur(gray,(15,15),0)cv2.namedWindow('polygonContours')cv2.createTrackbar('epsilon','polygonContours',10,200,onChange)cv2.createTrackbar('threshold','polygonContours',120,255,onChange)while(True):epsilon=cv2.getTrackbarPos('epsilon','polygonContours')thres=cv2.getTrackbarPos('threshold','polygonContours')_,thresh=cv2.threshold(blur,thres,255,cv2.THRESH_BINARY)contours,hier=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)frame=img.copy()forcincontours:#对轮廓进行多边形逼近approx=cv2.approxPolyDP(c,epsilon,True)cv2.drawContours(frame,[approx],-1,(255,0,255),2)#检测图形边界框并绘制x,y,w,h=cv2.boundingRect(approx)cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),3)#检测最小封闭区间(矩形)并绘制rect=cv2.minAreaRect(approx)box=cv2.boxPoints(rect)box=np.intp(box)cv2.drawContours(frame,[box],0,(0,0,255),3)#检测最小封闭区间圆形并绘制(x,y),radius=cv2.minEnclosingCircle(approx)center=(int(x),int(y))radius=int(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读取彩色图像img=cv2.imread('4.jfif',cv2.IMREAD_COLOR)#将彩色图像转化为灰度图像gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#进行高斯滤波处理blur=cv2.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是分别获取两个滑动条的值epsilon=cv2.getTrackbarPos('epsilon','polygonContours')thres=cv2.getTrackbarPos('threshold','polygonContours')#这里就根据我们要二值处理的 rhres这个参数传入进行二值处理,作为判断的阈值_,thresh=cv2.threshold(blur,thres,255,cv2.THRESH_BINARY)#寻找轮廓处理contours,hier=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)frame=img.copy()forcincontours:#对轮廓进行多边形逼近#approxPolyDP#第一个表示我们输出轮廓的 (点集)#第二个参数表示 逼近精度 ,值越小 表面逼近精度越精确,值越大,表面轮廓越简化#true 表示多边形是闭合的approx=cv2.approxPolyDP(c,epsilon,True)#表示绘制我们多边形逼近结果cv2.drawContours(frame,[approx],-1,(255,0,255),2)#检测图形边界框并绘制#boundingRect 绘制我们的矩形外框 (绿色)x,y,w,h=cv2.boundingRect(approx)cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),3)#检测最小封闭区间(矩形)并绘制#minAreaRect 绘制最小外接矩阵(红色)rect=cv2.minAreaRect(approx)box=cv2.boxPoints(rect)box=np.intp(box)cv2.drawContours(frame,[box],0,(0,0,255),3)#检测最小封闭区间圆形并绘制#minEnclosingCircle 绘制最小外接圆(蓝色)(x,y),radius=cv2.minEnclosingCircle(approx)center=(int(x),int(y))radius=int(radius)cv2.circle(frame,center,radius,(255,0,0),2)#轮廓绘制cv2.imshow('polygonContours',frame)ifcv2.waitKey(100)==27:break在这里插入图片描述