1、方法一、先计算轮廓
本人对该方法,基于轮廓计算的实用性表示怀疑,哈哈。
(1)先灰度化
(2)阈值分割
(3)找到轮廓
(4)计算获取面积,宽高比,外接矩,中心点
#引入opencv模块
import cv2 as cv
#引入numpy模块
import numpy as np
#引入sys模块
import sys
#measure
def measure_object(img):
#(1)灰度化,阈值分割,注意,黑色里面找白色,所以THRESH_BINARY_INV取反了下
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
print("threshold value: %s"%(ret)) #分割的阈值
cv.namedWindow("binary_image",cv.WINDOW_NORMAL)
cv.imshow("binary_image",binary)
#(2)获取最外层轮廓
contours,heriachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
#(3)计算获取面积,宽高比,外接矩,中心点
for i,contour in enumerate(contours):
area = cv.contourArea(contour)
print("contour: %s ,area: %s"%(i,area))
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(img,(np.int(cx),np.int(cy)),3,(0,255,255),-1)
cv.rectangle(img,(x,y),(x+w,y+h),(0,0,255,2))
cv.namedWindow("measure_contours",cv.WINDOW_NORMAL)
cv.imshow("measure_contours",img)
def img_test():
img = cv.imread('E:/chenopencvblogimg/measure.jpg')
#判断是否读取成功
if img is None:
print("Could not read the image,may be path error")
return
cv.namedWindow("origin Pic",cv.WINDOW_NORMAL)
cv.imshow("origin Pic",img)
measure_object(img)
#让显示等待键盘输入维持在那里,否则程序跑完就闪退啦!
cv.waitKey(0)
#销毁窗口
cv.destroyAllWindows()
if __name__ == '__main__':
sys.exit(img_test() or 0)
2、多边形拟合,判断三角形,矩形和圆形
#引入opencv模块
import cv2 as cv
#引入numpy模块
import numpy as np
#引入sys模块
import sys
#approxCurve
def approxCurve_test(img):
#(1)灰度化,阈值分割,注意,黑色里面找白色
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
print("threshold value: %s"%(ret)) #分割的阈值
cv.namedWindow("binary_image",cv.WINDOW_NORMAL)
cv.imshow("binary_image",binary)
#绘图用
dst = cv.cvtColor(gray,cv.COLOR_GRAY2BGR)
#(2)获取最外层轮廓
contours,heriachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
#(3)计算获取面积,宽高比,外接矩,中心点
for i,contour in enumerate(contours):
approxCurve = cv.approxPolyDP(contour,4,True)
#print(i)
print(approxCurve.shape)
#需要很多条边去拟合,比如圆形
if approxCurve.shape[0]>6:
cv.drawContours(dst,contours,i,(255,255,0),4)
#需要4边去拟合,比如矩形
if approxCurve.shape[0]==4:
cv.drawContours(dst,contours,i,(0,255,255),4)
#需要3边去拟合,比如三角形
if approxCurve.shape[0]==3:
cv.drawContours(dst,contours,i,(0,0,255),4)
cv.namedWindow("approxCurve_test",cv.WINDOW_NORMAL)
cv.imshow("approxCurve_test",dst)
def img_test():
img = cv.imread('E:/chenopencvblogimg/measure2.jpg')
#判断是否读取成功
if img is None:
print("Could not read the image,may be path error")
return
cv.namedWindow("origin Pic",cv.WINDOW_NORMAL)
cv.imshow("origin Pic",img)
approxCurve_test(img)
#让显示等待键盘输入维持在那里,否则程序跑完就闪退啦!
cv.waitKey(0)
#销毁窗口
cv.destroyAllWindows()
if __name__ == '__main__':
sys.exit(img_test() or 0)