opencv 轮廓与边缘的区别/轮廓检测方法
边缘是零散的,轮廓是一个整体。
感觉用途不大,因为一般图像的轮廓多且每个轮廓都很小,
import cv2 import numpy as np img=cv2.imread('C:/Users/59925/Desktop/pytest/pics/white_circle.png') gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #先做二值化结果,为了能更好地进行边缘检测 retval,thresh=cv2.threshold(gray,127,255,cv2.THRESH_BINARY) #retval是返回的阈值;thresh是返回的二值化图像 binary,contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) #cv2.RETR_TREE指定轮廓返回mode;cv2.CHAIN_APPROX_NONE指定轮廓的近似方法 #hierarchy存储轮廓的属性信息,与cv2.RETR_TREE 相关。 #contours是轮廓结果 #print(hierarchy) draw_img=img.copy() #(0,152,255)BGR信道指定绘制轮廓的线条颜色;后面数字指定绘制的线条的粗细。 #-1,表示绘制所有轮廓线条, draw_img=cv2.drawContours(draw_img,contours,-1,(0,0,255),1) cv2.imshow('draw_img',draw_img) cv2.imshow('binary',binary) cv2.waitKey(10) cv2.destroyAllWindows() #进行轮廓特征计算 contour0=contours[0]#取出其中一条轮廓 draw_img0=img.copy() draw_img0=cv2.drawContours(draw_img0,[contour0],0,(0,0,255),2) cv2.imshow('draw_img0',draw_img0) cv2.waitKey(10) cv2.destroyAllWindows() area=cv2.contourArea(contour0)#计算轮廓面积 length=cv2.arcLength(contour0,True)#计算轮廓周长,True表示其是一个整体,是闭合的 print(area,length) #轮廓特征与近似 epsilon=0.1*length draw_approx=img.copy() #epsilon为近似去轮廓曲线的最小精度。#epsilon越小近似轮廓越接近原轮廓。 approx=cv2.approxPolyDP(contour0,epsilon,True) draw_approx=cv2.drawContours(draw_approx,[approx],-1,(0,0,255),1) cv2.imshow('draw_approx',draw_approx) cv2.waitKey(0) cv2.destroyAllWindows() #边界圆或边界矩形。为了得到更多特征。 x,y,w,h=cv2.boundingRect(contours[0])#得到边界矩形信息x,y为坐标点,w为宽,h为高 rect=img.copy() rect=cv2.rectangle(rect,(x,y),(x+w,y+h),(0,0,255),2) cv2.imshow('rect',rect) cv2.waitKey(10) cv2.destroyAllWindows() #计算轮廓面积在边界矩形中的占比 rect_area=w*h percent=area/rect_area print(percent) #外接圆 (x,y),radius=cv2.minEnclosingCircle(contour0) enclosing_circle=img.copy() enclosing_circle=cv2.circle(enclosing_circle,(int(x),int(y)),int(radius),(0,0,255),2) cv2.imshow('enclosing_circle',enclosing_circle) cv2.waitKey(0) cv2.destroyAllWindows() circle_area=np.pi*np.power(radius,2) percent=area/circle_area print(percent)
画出所有轮廓
获取近似轮廓(红色)
画出轮廓边界矩形,并计算轮廓面积占比
画出轮廓边界圆