OpenCV学习笔记-轮廓性质

这篇文章我们学习提取一些经常使用的对象特征,不过我并不知道有什么用,如果哪位在生产中用到这些特征,请在评论里说下用处,谢谢大家,一起进步。
涉及的特征有:
1、边界矩形的宽高比
2、轮廓面积与边界矩形面积的比
3、轮廓面积与凸包面积的比
4、与轮廓面积相等的圆形的直径
5、方向
6、掩模和像素点
7、最大值和最小值以及它们的位置
8、平均颜色和平均灰度
9、极点


鉴于特征比较多,所以我把它们整合到一起,可以更直观的看出:

def nature_demo(img):
    #灰度化
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    #二值化
    ret, thresh = cv.threshold(gray, 127, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    cv.imshow('thresh image', thresh)

    #寻找轮廓
    copyImage, contours, hireachy = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for i, contour in enumerate(contours):
        print(i)

        #边界矩形的宽高比
        x, y, w, h = cv.boundingRect(contour)
        img = cv.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
        aspect_ratio = float(w)/h
        print('边界矩形的宽高比', aspect_ratio)

        #轮廓面积与边界矩形面积的比
        area  = cv.contourArea(contour)
        rect_area = w*h
        extent = float(area)/rect_area
        print('extent', extent)

        #轮廓面积与凸包面积的比
        hull = cv.convexHull(contour)
        cv.drawContours(img, [hull], i, (0, 255, 0), 2)
        hull_area = cv.contourArea(hull)
        solidity = float(area)/hull_area
        print('solidity', solidity)

        #与轮廓面积相等的圆形的直径
        equi_diameter = np.sqrt(4*area/np.pi)
        print('equivalent diameter', equi_diameter)

        #方向即对象相对于X轴的旋转角度, 还会返回长轴和短轴的长度
        (x, y), (MA, ma), angle = cv.fitEllipse(contour)
        print('方向',x, y, MA, ma, angle)

        #掩模和像素点
        mask = np.zeros(gray.shape, np.uint8)
        cv.drawContours(mask, [contour], 0, 255, -1)

        # pixelpoints = np.transpose(np.nonzero(mask)) #返回的坐标形势是(row, column)
        pixelpoints = cv.findNonZero(mask) # 返回的坐标形式是(x, y) row=y column = x
        #返回结果是构成图像的所有像素点
        print('构成图像的像素点', pixelpoints)

        #最大值和最小值及它们的位置  我们用掩模图像得到这些参数
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(gray, mask=mask)
        print('最大值和最小值及它们的位置', min_val, max_val, min_loc, max_loc)

        #平均颜色和平均灰度
        mean_val = cv.mean(img, mask=mask)
        print('平均颜色和平均灰度', mean_val)

        #极点 一个对象最上面,最下面,最左边,最右边的点
        leftmost = tuple(contour[contour[:, :, 0].argmin()][0])
        rightmost = tuple(contour[contour[:, :, 0].argmax()][0])
        topmost = tuple(contour[contour[:, :, 1].argmin()][0])
        bottommost = tuple(contour[contour[:, :, 1].argmax()][0])
        print('极点', leftmost, rightmost, topmost, bottommost)

    cv.imshow('contours image', img)
我们来看一下输出结果:

边界矩形的宽高比 0.7389380530973452

extent 0.36985321392613

solidity 0.6486222759165466

equivalent diameter 133.31598105612895

方向 264.66644287109375 204.49493408203125 110.507080078125 219.6423797607422 27.516525268554688

构成图像的像素点 [[[267 109]]
 [[268 109]]
 [[269 109]]
 ...
 [[206 332]]
 [[205 333]]
 [[205 334]]]

最大值和最小值及它们的位置 72.0 197.0 (232, 239) (284, 231)

平均颜色和平均灰度 (41.84801501772927, 37.535423764166026, 216.375095598971, 0.0)

极点 (194, 225) (360, 162) (267, 109) (205, 334)

猜你喜欢

转载自blog.csdn.net/qq_36387683/article/details/80470594