基于人工智能实验平台的OpenCV多边形逼近对象检测
1.实验目的
熟悉opencv读入图片,绘制多边形边框.
2.实验设备
安装了python和pychrm的电脑一台。
3.实验内容
包含图片的导入、绘制矩形、显示图片。
4.实验原理
在OpenCV中,寻找的物体是白色的,而背景必须是黑色的,因此图片预处理时必须保证这一点。所以在轮廓检测之前,首先要对图片进行二值化或者Canny边缘检测。
我们将图像二值化后,用findContours函数就可以很方便的找出图像的轮廓信息,循环遍历每一个信息点,cv2.rectangle函数画出来即可。
质心:
首先,使用findContour()函数找出图像中包含的轮廓信息,然后对所有轮廓进行遍历,并计算每一个轮廓的力矩(Moment),就可以得出物体的质心位置:

轮廓近似:
将轮廓形状近似到另外一种由更少点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定。为了帮助理解,假设我们要在一幅图像中查找一个矩形,但是由于图像的种种原因,我们不能得到一个完美的矩形,而是一个“坏形状”(如下图所示)。现在你就可以使用这个函数来近似这个形状()了。这个函数的第二个参数叫epsilon,它是从原始轮廓到近似轮廓的最大距离。它是一个准确度参数。选择一个好的 epsilon 对于得到满意结果非常重要。
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

轮廓检测
approxPolyDP()函数是opencv中对指定的点集进行多边形逼近的函数,其逼近的精度可通过参数设置,返回参数是输出的点集,当前点集是能最小包容指定点集的,画出来即是一个多边形。主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。
函数原型:
approxPolyDP(contourMat, double , closed)
第一个参数 contourMat:即轮廓的点集信息
第二个参数double epsilon:是一个距离值,即是原始曲线与近似曲线之间的最大距离,表示多边形的轮廓接近实际轮廓的程度,值越小,越精确
第三个参数bool closed:若为tru,则说明近似曲线是闭合的,反之,若为false,则断开。
该函数采用是道格拉斯-普克算法(Douglas-Peucker)来实现。该算法也以Douglas-Peucker算法和迭代终点拟合算法为名。是将曲线近似表示为一系列点,并减少点的数量的一种算法。
经典的Douglas-Peucker算法描述如下:
(1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦;
(2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离d;
(3)比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕。
(4)如果距离大于阈值,则用C将曲线分为两段AC和BC,并分别对两段取信进行1~3的处理。
(5)当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。
示意图:
轮廓面积:
轮廓的面积可以使用函数 cv2.contourArea() 计算得到,也可以使用矩(0 阶矩),M[‘m00’]。
area = cv2.contourArea(cnt)
轮廓周长:
也被称为弧长。可以使用函数 cv2.arcLength() 计算得到。这个函数的第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)。
perimeter = cv2.arcLength(cnt,True)
5 实验步骤
打开pycharm。我们右击相应的文件目录,选择new—>点击Python File,然后输入新建的文件名,点击确定,相应的.py文件就建好了,可以进行编写代码了。
ipoert cv2
读取图片。
image=cv2.imread('..\images\\kasi.png')
将图像转为灰度图像。
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #转灰度图像
将图像转换为HSV。
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)#转变成hsv
threshold二值化处理 当前点值大于阈值时,设置为0,否则设置为Maxval。
ret, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
寻找目标轮廓;轮廓计算函数cv2.RETR_EXTERNAL只检测最外围轮廓;cv2.CHAIN_APPROX_SIMPLE仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours。
contours,hireachy = cv2.findContours(binary,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
boundingRect计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的;moments几何矩,moments()来计算图像中的中心矩,mm是字典类型。
for i, contour in enumerate(contours):
x, y, w, h = cv2.boundingRect(contour) # 外接矩形
mm = cv2.moments(contour)
计算中心点并绘制。
cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00']
cv2.circle(image, (np.int(cx), np.int(cy)), 3, (0, 255, 255), -1)
多边形拟合。
approxCurve = cv2.approxPolyDP(contour, 4, closed=True)
approxCurve.shape[0]获取多边形轮廓边数,进行判断绘制不同颜色。
if approxCurve.shape[0] > 6: # 边数大于6,近似圆形,椭圆
cv2.drawContours(image, contours, i, (255, 255, 0), 2)
if approxCurve.shape[0] == 3: # 三角形
cv2.drawContours(image, contours, i, (0, 0, 255), 2)
if approxCurve.shape[0] == 4: # 四角形
cv2.drawContours(image, contours, i, (0, 255, 125), 2)
显示绘制轮廓的图像。
cv2.imshow('a',image)
cv2.waitKey()
可以看到效果如下。

运行结果图
更多推荐

所有评论(0)