轮廓特征
查找轮廓的不同特征,例如矩、面积、周长等。
-
图像矩
原始矩
对于二维连续函数阶的矩被定义为
图像矩对于=0,1,2…对于灰度图像的像素的强度,原始图像的矩被计算为
图像中心矩
中心矩被定义为
标准化的中心距标准化中心距的定义:
图像矩作用- 二值图像的面积或灰度图像的像素总和,可以表示为:
-
图像的几何中心可以表示为:
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)
网友评论