先斩后奏,源码:
import cv2
import numpy as np
from scipy import signal
import math
imgname = 'S:\\AdobeppPS\\SKOO\\cc33.jpg'
image = cv2.imread(imgname, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
h,w = image.shape[:2]
print('imagesize={}-{}'.format(w,h))
ret, img_bin = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
img_bin = cv2.erode(img_bin,kernel,iterations = 1)
cv2.imshow("img_bin",img_bin)
contours , hierarchy = cv2.findContours(img_bin , cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))
print("dgcaijid",len(hierarchy))
largest = None
show = False
FIRST = 0
RED = (0, 0, 255)
THICKNESS = 3
for contour in contours:
approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
if len(approx) == 3:
if largest is None or cv2.contourArea(contour) > cv2.contourArea(largest):
largest = contour
show = True
if show:
cv2.drawContours(image, [largest], FIRST, RED, THICKNESS)
cv2.imshow("Image",image)
cv2.waitKey(0)
数据输出: 参考来源:https://www.freesion.com/article/6289910425/ 根据周长和面积对一些轮廓进行处理。比如怎么样识别轮廓是一个三角形组成呢?显然就可看它是否有三条边组成的。如果一堆三角形里,还要找一个最大面积的三角形呢? 这时就需要使用OpenCV的函数: arcLength、contourArea、approxPolyDP,相关的函数定义如下:
1、计算周长参数详解 arcLength 函数 基本格式; CV-C++/ double cv::arcLength(InputArray curve,bool closed) python: cv2.arcLength(InputArray curve,bool closed)
(1) 第一个参数,InputArray curve,一般是由图像的轮廓点组成的点集; (2) 第二个参数,bool closed,表示输出的多边形是否封闭;true表示封闭,false表示不封闭;这个函数用来计算周长。 2、计算面积参数详解 contourArea 函数 基本格式; CV-C++/ double cv::contourArea(InputArray contour,bool oriented) python: cv2.contourArea(InputArray contour,bool oriented)
(1) 第一个参数,InputArray contour,一般是由图像的轮廓点组成的点集; (2) 第二个参数,bool oriented,如果设置为true时,表示返回有正负号的面积(根据点的顺序方向),否则返回绝对值。 这个函数用来计算面积。
3、拟合折线参数详解 approxPolyDP 函数 基本格式; CV-C++/ double cv::approxPolyDP(InputArray contour,OutputArray approxCurve, double epsilon,bool closed) python: cv2.approxPolyDP(InputArray contour,OutputArray approxCurve, double epsilon,bool closed)
(1) 第一个参数,InputArray contour,一般是由图像的轮廓点组成的点集; (2) 第二个参数,OutputArray approxCurve,表示输出的多边形点集; (3) 第三个参数,double epsilon:主要表示输出的精度,就是另个轮廓点之间最大距离数。 (4) 第四个参数,bool closed:表示输出的多边形是否封闭,布尔操作 主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。
简言之,对于cv的函数周长面积的参数,或者换句话说: ContourArea 计算整个轮廓或部分轮廓的面积 double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ ); contour 代表的是轮廓 (定点的序列或数组). slice 代表的是感兴趣特征轮廓部分的起始点,缺省是计算整个轮廓的面积。 对后面的情况,面积表示轮廓部分和起始点连线构成的封闭部分的面积。 注意: 轮廓的方向影响面积的符号。因此函数也许会返回负的结果。应用函数 fabs() 得到面积的绝对值。 ArcLength 计算轮廓周长或曲线长度 double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 ); curve 曲线点集序列或数组 slice 曲线的起始点,缺省是计算整个曲线的长度 is_closed 表示曲线是否闭合,有三种情况: is_closed=0 ——假设曲线不闭合 is_closed>0 ——假设曲线闭合 is_closed<0 ——若曲线是序列,检查 ((CvSeq*)curve)->flags 中的标识 CV_SEQ_FLAG_CLOSED 来确定曲线是否闭合。否则 (曲线由点集的数组 (CvMat*) 表示) 假设曲线不闭合。 函数 cvArcLength 通过依次计算序列点之间的线段长度,并求和来得到曲线的长度参考自博客 有效性不太好,对多个轮廓。 参考其他
|