本文将从多个方面对Python轮廓检测和轮廓绘制进行详细阐述。
一、轮廓检测
图像处理中的轮廓是图像中的连通区域边缘的曲线。可通过轮廓检测来获得物体的形状信息,常用于物体的识别和分割等应用。
1、轮廓检测方法
OpenCV中提供了多种轮廓检测方法,包括CHAIN_APPROX_NONE、CHAIN_APPROX_SIMPLE、CHAIN_APPROX_TC89_L1等,其中最常使用的是CHAIN_APPROX_SIMPLE。下面是轮廓检测的基本代码:
import cv2 img = cv2.imread('image.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img,contours,-1,(0,0,255),2) cv2.imshow('contours', img) cv2.waitKey(0)
2、轮廓特征
通过轮廓检测得到轮廓信息后,可以获取轮廓的面积、周长、重心、边界框等信息。下面是获取轮廓特征的代码:
import cv2 img = cv2.imread('image.png') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] M = cv2.moments(cnt) print('Area:', cv2.contourArea(cnt)) # 获取轮廓面积 print('Perimeter:', cv2.arcLength(cnt,True)) # 获取轮廓周长 print('Centroid:', (int(M['m10']/M['m00']), int(M['m01']/M['m00']))) # 获取轮廓重心 x,y,w,h = cv2.boundingRect(cnt) # 获取边界框 cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) cv2.imshow('contours',img) cv2.waitKey(0)
二、轮廓绘制
轮廓绘制常用于在图像上标注物体的边缘或者绘制几何形状等。
1、绘制单个轮廓
绘制单个轮廓的方法是通过cv2.drawContours()函数,下面是绘制单个轮廓的基本代码:
import cv2 import numpy as np img = np.zeros((300,300,3), dtype='uint8') # 创建黑色图像 pts = np.array([[50,50],[50,150],[150,150],[150,50]], np.int32) # 坐标点 pts = pts.reshape((-1,1,2)) # 调整坐标形状 cv2.drawContours(img, [pts], -1, (0,255,0), 3) # 绘制轮廓 cv2.imshow('contours',img) cv2.waitKey(0)
2、绘制多个轮廓
绘制多个轮廓时,可以通过for循环遍历每个轮廓进行绘制。下面是绘制多个轮廓的基本代码:
import cv2 import numpy as np img = np.zeros((300,300,3), dtype='uint8') # 创建黑色图像 pts1 = np.array([[50,50],[50,150],[150,150],[150,50]], np.int32) pts2 = np.array([[200,50],[200,150],[300,150]], np.int32) pts1 = pts1.reshape((-1,1,2)) pts2 = pts2.reshape((-1,1,2)) cv2.drawContours(img, [pts1], -1, (0,255,0), 3) cv2.drawContours(img, [pts2], -1, (255,0,0), 3) cv2.imshow('contours',img) cv2.waitKey(0)
3、绘制凸包
凸包是能够包含所有轮廓点的最小凸多边形,可以通过cv2.convexHull()函数获取凸包。下面是绘制凸包的基本代码:
import cv2 import numpy as np img = np.zeros((300,300,3), dtype='uint8') # 创建黑色图像 pts = np.array([[50,50],[50,150],[150,150],[150,50]], np.int32) pts = pts.reshape((-1,1,2)) hull = cv2.convexHull(pts) # 获取凸包 cv2.drawContours(img, [pts], -1, (0,255,0), 3) cv2.drawContours(img, [hull], -1, (0,0,255), 3) cv2.imshow('contours',img) cv2.waitKey(0)
4、绘制轮廓拟合直线或椭圆
可以通过cv2.fitLine()函数对轮廓进行直线拟合,或者通过cv2.fitEllipse()函数对轮廓进行椭圆拟合,下面是绘制轮廓拟合直线或椭圆的基本代码:
import cv2 import numpy as np img = cv2.imread('image.png') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray,50,150) lines = cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength=50,maxLineGap=10) # 检测直线 for line in lines: x1,y1,x2,y2 = line[0] cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) # 绘制直线 gray = cv2.GaussianBlur(gray,(5,5),0) # 高斯滤波 _, contours, _ = cv2.findContours(gray,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) cnt = contours[0] ellipse = cv2.fitEllipse(cnt) # 椭圆拟合 cv2.ellipse(img, ellipse, (0, 255, 0), 2) # 绘制椭圆 cv2.imshow('contours',img) cv2.waitKey(0)
三、总结
本文详细介绍了Python轮廓检测和轮廓绘制的方法及应用,包括轮廓检测的方法和轮廓特征获取,以及轮廓绘制的多种方法,包括绘制单个轮廓、绘制多个轮廓、绘制凸包和轮廓拟合直线或椭圆等。通过本文的学习,读者可以全面掌握Python图像处理中的轮廓检测和轮廓绘制技术。