1、弧长与面积
①轮廓发现;
②计算每个轮廓的弧长与面积,像素单位;
2、多边形拟合
①获取轮廓的多边形拟合结果(approxPolyDP)
espilon越小折线越逼近真实形状
close是否为闭合区域
3、几何矩计算
①原点矩;
②中心矩;
③图像重心坐标;
注:OTSU二值化可能会丢失数据
# 对象测量
from matplotlib import pyplot as plt
from cv2 import cv2 as cv
import numpy as np
# 采用canny边缘提取
def edge_demo(image):
blurred = cv.GaussianBlur(image,(3,3),0) #高斯降噪,适度
gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)
#求梯度
xgrd = cv.Sobel(gray,cv.CV_16SC1,1,0)
ygrd = cv.Sobel(gray,cv.CV_16SC1,0,1)
egde_output = cv.Canny(xgrd,ygrd,50,150) #50低阈值,150高阈值
#egde_output = cv.Canny(gray,50,150) #都可使用
cv.imshow('canny_edge',egde_output)
return egde_output
def measure_object(image):
# dst = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
# ret,binary = cv.threshold(dst,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
# print('threshold valus: %s'%ret)
# cv.imshow('binary image',binary)
binary = edge_demo(image)
dst = cv.cvtColor(binary,cv.COLOR_GRAY2BGR)
contours, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)#注意 我的版本只有两个返回参数,具体看函数说明是返回几个参数
for i,contour in enumerate(contours):
area = cv.contourArea(contour)
rect = cv.boundingRect(contour)#得到轮廓的外接矩形
x,y,w,h = cv.boundingRect(contour)
rate = min(w,h)/max(w,h)#宽高比
print('%d rectangle rate:%s'%(i,rate))
mm = cv.moments(contour)#得到几何矩
#print(mm) #为啥不一样?为啥黑色的背景就没有问题
type(mm)
cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00'] #得到图像重心(中心)位置
cv.circle(dst,(np.int(cx),np.int(cy)),2,(0,255,255),-1)#标记中心点
#cv.rectangle(dst,(x,y),(x+w,y+h),(0,0,255),2)#绘制外接矩形
print('contour area:%s'%area)
#多边形拟合
approxCurve = cv.approxPolyDP(contour,4,True)
print(approxCurve.shape)
if approxCurve.shape[0] > 6:#画圆、椭圆
cv.drawContours(dst,contours,i,(0,255,0),2)
if approxCurve.shape[0] == 4:#矩形恒等于4
cv.drawContours(dst,contours,i,(0,0,255),2)
if approxCurve.shape[0] == 3:#三角形恒等于3
cv.drawContours(dst,contours,i,(255,0,0),2)
if approxCurve.shape[0] == 6:#六边形恒等于6
cv.drawContours(dst,contours,i,(255,0,0),2)
cv.imshow('measure_contour',dst)
cv.imwrite("C:\\pictures\\others\\012345678.jpg",dst)
if __name__ == "__main__":
filepath = "C:\\pictures\\others\\measure1.png"
img = cv.imread(filepath) # blue green red
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",img)
measure_object(img)
cv.waitKey(0)
cv.destroyAllWindows()
结果如下:

本文详细介绍了一种基于边缘检测的图像轮廓分析方法,通过Canny边缘检测算法和轮廓发现,实现了图像中对象的弧长与面积计算、多边形拟合及几何矩计算。文章还介绍了如何使用OpenCV进行对象测量,包括轮廓发现、计算弧长与面积、多边形拟合及几何矩计算等关键步骤。
1705

被折叠的 条评论
为什么被折叠?



