【OpenCV + Python】轮廓特性

函数cv2.drawContours()被用来绘制轮廓。第一个参数是一张图片,可以是原图或者其他。第二个参数是轮廓,也可以说是cv2.findContours()找出来的点集,一个列表。第三个参数是对轮廓(第二个参数)的索引,当需要绘制独立轮廓时很有用,若要全部绘制可设为-1。接下来的参数是轮廓的颜色和厚度。
在这里插入图片描述
凸形形状的轮廓检测:凸形指图形内两点连线可能会在图形外,OpenCV中应用道格拉斯-普客算法检测凸形的轮廓,内置函数为:cv2.approxPolyDP(contours, epsilon, flag) 三个参数分别为轮廓点、轮廓线与轮廓的最大差异值、表示轮廓是否封闭的bool型变量flag。 最重要的当然是epsilon的值,他越小,代表这一新轮廓越接近旧的轮廓。

import cv2
import numpy as np
def edge_demo(image):
    blurred = cv2.GaussianBlur(image, (3, 3), 0)
    gray = cv2.cvtColor(blurred, cv2.COLOR_RGB2GRAY)
    # xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) #x方向梯度
    # ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) #y方向梯度
    # edge_output = cv.Canny(xgrad, ygrad, 50, 150)
    edge_output = cv2.Canny(gray, 220, 250)

    return edge_output

def contour(img):
    binary = edge_demo(img)
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    for i,contour in enumerate(contours):
        cv2.drawContours(img, contours, -1, (0, 0, 255),2)
        area = cv2.contourArea(contour)
        print("轮廓个数: %s" % str(i))
        print("area: %s"%area)
        x,y,w,h = cv2.boundingRect(contour)
        rate = min(w,h)/max(w,h)
        print("横纵比例:%s"%str(rate))
        mm = cv2.moments(contour)
        print(type(mm))
        cx = mm['m10']/mm['m00']
        cy = mm['m01'] / mm['m00']
        print("cx:%s" % str(np.int(cx)))
        print("cy:%s" % str(np.int(cy)))
        cv2.circle(img,(np.int(cx),np.int(cy)),6,(255,255,0),-1)
        cv2.rectangle(img,(x-2,y-2),(x+w+2,y+h+2),(255,0,0),5)
    cv2.imshow('img', img)


img = cv2.imread('14.jpg',1)
cv2.namedWindow('img', 0)
cv2.namedWindow('imgsrc', 0)
cv2.namedWindow('Canny Edge', 0)
cv2.resizeWindow('img', 480, 400)
cv2.resizeWindow('imgsrc', 480, 400)
cv2.resizeWindow('Canny Edge', 480, 400)
cv2.imshow('imgsrc', img)
#edge_demo(img)
contour(img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
轮廓个数与面积计算:

area = cv2.contourArea(contour)
print("轮廓个数: %s" % str(i))
print("area: %s"%area)

横纵比例筛选:

x,y,w,h = cv2.boundingRect(contour)
rate = min(w,h)/max(w,h)
print("横纵比例:%s"%str(rate))

中心矩:

cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00']
print("cx:%s" % str(np.int(cx)))
print("cy:%s" % str(np.int(cy)))
cv2.circle(img,(np.int(cx),np.int(cy)),6,(255,255,0),-1)

直接画出全部轮廓:

cv2.drawContours(binary, contours,-1, (0, 0, 255), 3)

判断图形个数:

import cv2
import numpy as np
def contour(img):
    dst = cv2.GaussianBlur(img,(3,3),0)
    gray = cv2.cvtColor(dst,cv2.COLOR_BGR2GRAY)
    cv2.imshow('imgsrc', gray)
    ret,binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
    cv2.imshow("binary", binary)
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    #cv2.drawContours(img, contours,-1, (0, 0, 255), 3)
    for i,contour in enumerate(contours):
        cv2.drawContours(img,contours,i,(255,255,0),3)
        approxcurve = cv2.approxPolyDP(contour, 4, False)
        print(approxcurve.shape)
        if approxcurve.shape[0] >10:
            cv2.drawContours(img,contours,i,(255,255,0),3)
        if approxcurve.shape[0] ==4:
            cv2.drawContours(img, contours, i, (255, 0, 0), 3)
        if approxcurve.shape[0] == 3:
            cv2.drawContours(img, contours, i, (0, 255, 0), 3)
        #print(i)
    cv2.imshow('img', img)
img = cv2.imread('17.jpg',1)
cv2.imshow('imgsrc', img)
contour(img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhouzongzong/article/details/94356950
今日推荐