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()

可以看到效果如下。
在这里插入图片描述
运行结果图

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐