OpenCV数字图像处理与计算机视觉(python)OpenCV with Python By Example

轮廓特征之矩、面积、周长

2020-02-22  本文已影响0人  陨星落云
轮廓特征

查找轮廓的不同特征,例如矩、面积、周长等。

  1. 图像矩

    原始矩

    对于二维连续函数f(x,p+q)阶的矩被定义为
    M _ { p q } = \int _ { - \infty } ^ { \infty } \int _ { - \infty } ^ { \infty } x ^ { p } y ^ { q } f ( x , y ) d x d y
    图像矩

    对于p,q=0,1,2…对于灰度图像的像素的强度I(x,y),原始图像的矩M_{ij}被计算为
    M_ { p q} = \sum _ { x } \sum _ { y } x ^ { p } y ^ { q } I ( x , y )
    图像中心矩
    中心矩被定义为
    {Mu} _ { p q } = \sum _ { x } \sum _ { y } ( x - \bar { x } ) ^ { p } ( y - \bar { y } ) ^ { q } I ( x , y )
    标准化的中心距

    标准化中心距的定义:
    \mathrm { Nu } _ { p q } = \frac { \mathrm { Mu } _ { pq } } { \mathrm { M } _ { 00 } ^ { ( p+ q ) / 2 + 1 } }
    图像矩作用

    • 二值图像的面积或灰度图像的像素总和,可以表示为:M_{00}
    • 图像的几何中心可以表示为:


      image.png

函数 cv2.moments() 会将计算得到的矩以一个字典的形式返回。如下:

cv2.moments(cnt)

参数

cnt:findContours函数返回的轮廓参数

例:

import cv2 
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("my_mask.png")
# BGR转灰度图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 二值化
ret,thresh = cv2.threshold(img_gray,12,255,0)
plt.imshow(thresh)
# 查找轮廓
image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
img = cv2.drawContours(img,contours,-1,(0,255,0),3)
cnt = contours[0]
M = cv2.moments(cnt)
# 查看矩
print(M)
# 求面积
print(M['m00'])
# 计算轮廓几何中心
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
print(cx,cy)
# 将中心标记为红色
img[cy,cx]=(0,0,255)
# 显示图像
cv2.imshow('img',img) # 在原图上绘制轮廓
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

矩:
{'m00': 118836.5, 'm10': 40229442.666666664, 'm01': 30592125.5, 'm20': 15292343026.916666, 'm11': 10355876833.791666, 'm02': 8703205239.083332, 'm30': 6309976487782.301, 'm21': 3936335965411.1, 'm12': 2946102101582.433, 'm03': 2666709947918.0503, 'mu20': 1673563802.7673512, 'mu11': -403928.8841228485, 'mu02': 827862708.734909, 'mu30': 48344.759765625, 'mu21': -104247829.05792236, 'mu12': 34335401.97906494, 'mu03': 6479782.6591796875, 'nu20': 0.11850660846509918, 'nu11': -2.8602579739916363e-05, 'nu02': 0.058621727910628446, 'nu30': 9.930583684466686e-09, 'nu21': -2.1413733265042987e-05, 'nu12': 7.052896412060584e-06, 'nu03': 1.3310237607157145e-06}
M00:
118836.5
图像几何中心:
338 257
img.png

轮廓面积

轮廓的面积可以使用函数 cv2.contourArea() 计算得到,也可以使用矩(0 阶矩),M['m00']

area = cv2.contourArea(cnt)

轮廓周长

也被称为弧长。可以使用函数 cv2.arcLength() 计算得到。这个函数的第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)。

perimeter = cv2.arcLength(cnt,True)

例:求矩形的面积,周长,几何中心。

import cv2 
import numpy as np
import matplotlib.pyplot as plt

# 图像:利用Pohtoshp绘制的一个100*100像素大小的黄色矩形
img = cv2.imread("square.jpg")

# BGR转灰度图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 二值化,注意图像的灰度:黄色区域218,白色区域为255
ret,thresh = cv2.threshold(img_gray,220,255,0)
# thresh = cv2.Canny(img,100,200)

# 查找轮廓
image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# print(hierarchy)

# 绘制轮廓
img = cv2.drawContours(img,contours,1,(255,204,102),5)
# print(contours)

# 选择矩形轮廓,矩形实际大小为100*100像素
cnt = contours[1]

# 查看矩
M = cv2.moments(cnt)
# print(M)

# 求矩形面积
print('矩形面积:',M['m00'])
area = cv2.contourArea(cnt)
print('矩形面积:',area)

# 求矩形的周长
perimeter = cv2.arcLength(cnt,True)
print('矩形的周长',perimeter)

# 计算图像几何中心
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])


print('矩形几何中心:',cx,cy)

# 由于一个像素很难看清,将中心附近5*5的区域标记天蓝色
color = (255,204,102)
for i in range(5):
    for j in range(5):
        img[cy-2+i,cx-2+j] = color

# 显示图像
cv2.namedWindow('img',cv2.WINDOW_NORMAL)
cv2.imshow('img',img ) # 在原图上绘制轮廓
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

矩形面积: 10199.0
矩形面积: 10199.0
矩形的周长 401.65685415267944
矩形几何中心: 392 280
矩形面积,周长.png
参考资料:
参考书籍:《OpenCV-Python 中文教程》
参考网站:
https://baike.tw.wjbk.site/baike-%E7%9F%A9_(%E5%9B%BE%E5%83%8F)
上一篇下一篇

猜你喜欢

热点阅读