图像轮廓的获取可参考博文十七
一、相关原理
1,弧长和面积
对于弧长和面积,计算出来的轮廓单位都是像素
2,多边形拟合
每一个轮廓都是一系列的点,然后通过多边形进行拟合,无限的接近真实形状
相关API:cv.approxPolyDP(contour,4, True)
其中参数一:contour几何的轮廓
参数二:epsilon表示折线的大小,越小表示越接近真实形状
参数三:close表示是否为闭合区域,一般默认为True
3,几何矩计算
前景像素f(x,y)
原点矩:
p+q=0称为零阶矩,p+q=1称为一阶矩
中心距:
中心距已经是中心化之后的值,一般都是从一阶矩开始的
图像的重心坐标:
M10表示一阶(1+0=1)
二、将几何图像通过矩形框框出,并求出矩形面积
import cv2 as cv
import numpy as npdef 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)dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)outImage, contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):area = cv.contourArea(contour)x, y, w, h = cv.boundingRect(contour)rate = min(w, h)/max(w, h)print("rectangle rate : %s"%rate)#矩形面积mm = cv.moments(contour)print(type(mm))cx = mm['m10']/mm['m00']cy = mm['m01']/mm['m00']cv.circle(dst, (np.int(cx), np.int(cy)), 3, (0, 255, 255), -1)#圆心cv.rectangle(dst, (x, y), (x+w, y+h), (0, 0, 255), 2)#矩形框print("contour area %s"%area)cv.imshow("measure-contours", dst)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\number.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
measure_object(src)
cv.waitKey(0)cv.destroyAllWindows()
效果图如下:
三、识别圆、矩形、三角形并使用不同的颜色进行区分标记轮廓,并出去轮廓面积
import cv2 as cv
import numpy as npdef 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)dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)outImage, contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for i, contour in enumerate(contours):area = cv.contourArea(contour)x, y, w, h = cv.boundingRect(contour)rate = min(w, h)/max(w, h)print("rectangle rate : %s"%rate)mm = cv.moments(contour)print(type(mm))cx = mm['m10']/mm['m00']cy = mm['m01']/mm['m00']cv.circle(dst, (np.int(cx), np.int(cy)), 3, (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:#矩形四条线段即可拟合成功cv.drawContours(dst, contours, i, (0, 0, 255), 2)if approxCurve.shape[0] == 3:#三角形三条线段即可拟合成功cv.drawContours(dst, contours, i, (255, 0, 0), 2)cv.imshow("measure-contours", dst)print("--------- Python OpenCV Tutorial ---------")
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\by.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
measure_object(src)
cv.waitKey(0)cv.destroyAllWindows()
效果图如下: