前言:
介绍opencv中如何图像轮廓检测,轮廓的识别,绘制轮廓。Canny边缘检测,霍夫变换的直线检测,圆形检测。还有些琐碎的概念,详细见目录。
近期在学习opencv,会更新一些基础的文章,一周一更(可能多更)。写这个博客就是,熟悉opencv的基本图像处理方法。练练手,最终做一个项目出来。
目录
凸包就是图形最外层的端点,将端点连接起来,可以围出一个包围图形的最小包围框,这个框作凸包。
一、图像的轮廓
1.轮廓检测
轮廓的检测在目标识别和分割、物体检测(工业自动化,医学图像处理领域有应用)、物体的分类和识别、视觉的引导和控制(机器人、自动驾驶需要视觉引导的应用,确定路径,确定障碍物)都有应用。
Contours,hierarchy=Cv2.findContours(img,mode,methode)
Mode:轮廓的检索模式
Methode:检测轮廓的方法
Contours:列表存储,每一个元素都是轮廓坐标的数组。
Mode参数值:
参数值 | 含义 |
cv2.RETR_EXTERNAL | 只检测外轮廓 |
cv2.RETR_LIST | 检测所有轮廓,但不建立层次关系 |
cV2.RETR_CCOMP | 检测所有轮廓,并建立.两级)层次关系 |
cv2.RETR_TREE | 检测所有轮廓,并建立树状结构的层次关系 |
检测轮廓的方法:
参数值 | 含义 |
cv2.CHAIN__APPROX_NONE | 储存轮廓上的所有点 |
cv2.CHAIN_APPROX_SIMPLE | 只保存水平、垂直或对角线轮廓的端点 |
cv2.CHAIN_APPROX_TC89_L1 | Ten-Chinl近似算法中的一种 |
cv2.CHAIN_APPROX_TC89_Kcos | Ten-Chinl近似算法中的一种 |
2.画轮廓
Img=Cv2.drawContours(image,contours,contourldx,color,thickness,lineType,hierarchy,maxLevel,offse)
lmage :被绘制轮廓的原始图像,可以时多通道图像
Contours :findContours ()方法得到的轮廓列表
Contourldx:绘制轮廓的索引 -1则绘制所有轮廓
Color :绘制颜色,使用BGR格式
Thickness :可选参数,画笔的粗细程度 -1则绘制实心图像
应用:检测多边形的轮廓
import cv2 img=cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\video-face\img_1\shape1.png")#彩色图像转变为单通道灰度图像 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度图像转为二值图像 t,binary=cv2.threshold(gray,127,255,cv2.THRESH_BINARY) print(t) #检测图像中出现的所有轮廓.记录轮廓的点 contours,hierarchy=cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE) #绘制所有轮廓,宽度为5颜色为红色 cv2.drawContours( img,contours,-1,(0,0,255),5) cv2.imshow( "img" ,img) cv2.waitKey() cv2.destroyAllwindows()
二、凸包
定义:
凸包就是图形最外层的端点,将端点连接起来,可以围出一个包围图形的最小包围框,这个框作凸包。
特点:
凸包是最逼近轮廓的多边形;
每一处都是凸出来的,任意三个点组成的内角均小于180度。
hull=cv2.convexHull(points,clockwise,returnPoints)
Point为轮廓数组
Clockwise 为true时点顺时针排列
Returnpoints 可选参数 布尔类型 true时返回点的坐标
Hull 凸包的点阵数组
应用:绘制多边形的凸包
import cv2 img=cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\video-face\img_1\shape2.png")#转换成灰度图 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#二值化阈值处理 ret,binary=cv2.threshold(gray,127,225,cv2.THRESH_BINARY) #检测图像中出现的所有轮廓 contours,hierarchy=cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) hull=cv2.convexHull(contours[0])#获得轮廓的凸包 cv2.polylines(img, [hull],True, (0,0,255),2)#绘制凸包 cv2.imshow( "img" ,img) cv2.waitKey() cv2.destroyAllWindows()
-
三、Canny边缘检测的方法
Canny边缘检测算法是一个多级边缘检测算法,根据像素梯度变化寻找图片的边缘,最终可以绘制十分精细的二值边缘图像。
Edges = cv2.Canny(img,threshold1,threshold2,apertureSize,L2gradient)
Threshold1 计算过程使用的第一个阈值,通常为最小阈值
Threshold2 计算过程使用的第2个阈值,通常为最大阈值
ApertureSize 可选参数 sobel算子的孔径大小
Edges 计算后的出的边缘图像 是一个二值灰度图像
绘制人物的漫画形式
import cv2 img=cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\video-face\img_1\meili.jpg") r1=cv2.Canny(img, 10,50) r2=cv2.Canny(img, 100,200) r3=cv2.Canny(img,400,600) cv2.imshow("img" ,img) cv2.imshow("r1",r1) cv2.imshow("r2" ,r2) cv2.imshow("r3" , r3) cv2.waitKey() cv2.destroyAllwindows()
-
四、霍夫变换
是一种特征检测,通过算法识别图像的特征,从而判断图像中的特殊形状。
直线检测
原理:霍夫坐标系的直线与笛卡尔坐标系的点之间的映射关系来判断图像中的点是否构成直线。
lines=cv2.HoughLinesP(image,rho,theta,threshold,minLineLength,maxLineGap)
rho检测直线使用的半径步长 值为1表示检测所有可能的半径步长
theta 搜索直线的角度
threshole 阈值该值越小,检测出的直线就越多
minLineLength 线段的最小长度,小于该长度的线段不记录到结果中
maxLineGap 线段的最小长度,小于改长度的直线不会记录到结果中
1.应用:霍夫变换直线检测-检测铅笔轮廓
import cv2
import numpy as np
img=cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\video-face\img_1\pen.jpg")
o=img.copy()#复制图像
o =cv2.medianBlur(o,5)
binary=cv2.Canny(o,50,150)
#检测直线,精度,全角度,阈值,线段最短,最小间隔
lines=cv2.HoughLinesP(binary,1,np.pi/180,15,minLineLength=100,maxLineGap=18)
for line in lines :
x1,y1,x2,y2=line[0]
cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)#画直线
cv2.imshow( "canny" ,binary)
cv2.imshow( "img" ,img)
cv2.waitKey()
cv2.destroyAllwindows()
圆环检测
cv2.HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None)
image 8位单通道图像,如果使用彩色图像,需要先转换成灰度图像
method:定义检测图像中圆的方法。cv2.HOUGH_GRADIENT ;
dp:图像像素分辨率与参数空间分辨率的比值,dp=1,则参数空间与图像像素空间(分辨率)一样大
minDist 检测到的圆的中心,(x,y )坐标之间的最小距离
如果minDist太小,则可能导致检测到多个相邻的圆。如果minDist太大,则可能导致很多圆检测不到;
param1 用于处理边缘检测的梯度值方法
param2 cv2.HOUGH_GRADIENT方法的累加器阈值。阈值越小,检测到的圆越多
minRadius 半径的最小大小(以像素为单位)
maxRadius 半径的最大大小(以像素为单位)
2.应用:用霍夫变换-圆形检测-检测出图片所有的药片
import cv2 import numpy as np img=cv2.imread(r"D:\Program Files (x86)\PyCharmProject\pythonProject\video-face\img_1\yaopian.jpeg") o=img.copy() o=cv2.medianBlur(o,5) gray=cv2.cvtColor(o,cv2.COLOR_BGR2GRAY) circles=cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,35,param1=100,param2=25,minRadius=10,maxRadius=50) circles=np.uint(np.around(circles)) for c in circles[0]: x,y,r= c cv2.circle(img,(x,y),r,(0,0,255),3) cv2.circle(img,(x,y),2,(0,0,255),3) print("检测到了" , len(circles[0]),"枚药片") cv2.imshow( "img " ,img) cv2.waitKey()
本次学习了解到了图像边缘检测的应用,图像边缘检测的方法,图像边缘的绘制方法,还了解到了凸包的定义和绘制方法,还有霍夫变换的直线检测和霍夫变换的圆形检测。
我对图像的边缘检测的医学应用的肿瘤的检测很感兴趣。对我最有启发的是霍夫变换的圆形检测,可以用于烧烤店的数签子的数量,减少人工。有想法针对串串香店开发一个数签字的小程序,方便大家使用也加深对霍夫变换的应用。