19. 对象测量

1. opencv 中轮廓特征包括:

  • 面积,周长,质心,边界框等
  • 弧长与面积测量
  • 多边形拟合
  • 获取轮廓的多边形拟合结果

2. python-opencv API提供方法:

  • cv2.moments()用来计算图像中的中心矩(最高到三阶),会将计算得到的的矩以一个字典的形式返回;
  • cv2.HuMoments()用于由中心矩计算Hu矩;
  • cv2.contourArea()函数计算轮廓面积;   参数有2个: 1. 轮廓 2. 来指定对象的形状是闭合的(True),还是打开的(一条曲线)
  • x, y, w, h = cv2.boudingrect() # 获得外接矩形     参数说明:x,y, w, h 分别表示外接矩形的左上角点的坐标,以及矩形的宽和高。
  • cv2.arcLength()来计算轮廓或曲线长度, 参数同上
  • cv2.aprroxPolyDP(cnt, epsilon, True)  # 用于获得轮廓的近似值,对指定的点集进行多边形逼近,使用cv2.drawCountors进行画图操作

     参数说明:cnt为输入的轮廓值, epsilon为阈值T,通常使用轮廓的周长作为阈值,值越小,折线越逼近真实形状;True表示的是轮廓是闭合的。

3. 实现代码:

import cv2 as cv
import numpy as np


def measure_object(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    print("threshold value: %s"%ret)               # 输出阈值
    cv.imshow("binary image", binary)

    contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

    # for i, contour in enumerate(contours):
    #     cv.drawContours(image, contours, i, (0, 0, 255), 2)  # 2为像素大小,-1时填充轮廓
    #     print(i)
    # cv.imshow("detect contours", image)

    for i, contour in enumerate(contours):
        cv.drawContours(image, contours, i, (0, 255, 255), 1)  # 用黄色线条画出轮廓

        area = cv.contourArea(contour)  # 计算轮廓面积
        print("contour area:", area)

        # 轮廓周长,第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)。
        perimeter = cv.arcLength(contour, True)

        print("contour perimeter:", perimeter)

        x, y, w, h = cv.boundingRect(contour)  # 轮廓的外界矩形
        cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)

        rate = min(w, h)/max(w, h)  # 计算矩阵宽高比
        print("rectangle rate",rate)

        mm = cv.moments(contour)  # 中心矩,函数 cv2.moments() 会将计算得到的矩以一个字典的形式返回
        # print(type(mm))         # 字典形式
        # 计算出对象的重心
        cx = mm['m10']/mm['m00']
        cy = mm['m01']/mm['m00']
        cv.circle(image, (np.int(cx), np.int(cy)), 2, (0, 255, 255), -1)  # 用实心圆画出重心

    cv.imshow("measure_object", image)


def contour_approx(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    print("threshold value: %s" % ret)
    cv.imshow("binary image", binary)

    contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for i, contour in enumerate(contours):
        cv.drawContours(image, contours, i, (0, 0, 255), 2)  # 用红色线条画出轮廓

        # 将轮廓形状近似到另外一种由更少点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定。
        # 这个函数的第二个参数叫 epsilon,它是从原始轮廓到近似轮廓的最大距离。
        # 它是一个准确度参数。选 择一个好的 epsilon 对于得到满意结果非常重要。

        epsilon = 0.01 * cv.arcLength(contour, True)
        approx = cv.approxPolyDP(contour, epsilon, True)
        cv.drawContours(image, approx, -1, (255, 0, 0), 10)

    cv.imshow("contour_approx", image)


def main():
    src = cv.imread("../images/handwriting.jpg")
    # cv.imshow("demo",src)
    # measure_object(src)

    img = cv.imread("../images/approximate.png")
    contour_approx(img)
    cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
    cv.destroyAllWindows()  # 关闭所有窗口


if __name__ == '__main__':
    main()

 

 

 

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值