OpenCV-Python快速入门(十二):轮廓拟合
- 前言
- 前提条件
- 实验环境
- 轮廓拟合
- 矩形包围框(cv2.boundingRect())
- 最小包围矩形框(cv2.minAreaRect())
- 最小包围圆形(cv2.minEnclosingCircle())
- 参考文献
前言
- 本文是个人快速入门OpenCV-Python的电子笔记,由于水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入
OpenCV-Python快速入门专栏或我的个人主页查看
前提条件
- 熟悉Python
实验环境
- Python 3.x (面向对象的高级语言)
- OpenCV 4.0(python第三方库)
pip3 install opencv-python
轮廓拟合
矩形包围框(cv2.boundingRect())
函数 cv2.boundingRect()能够绘制轮廓的矩形边界。
import numpy as np
import matplotlib.pyplot as plt
import cv2
# 读取图片
img = cv2.imread('2.jpg')
# BGR -> RGB
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(20, 20))
plt.subplot(2, 2, 1)
plt.title("Original")
plt.imshow(image)
# 灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 二值化
ret,binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
'''
retval = cv2.boundingRect( cnt )
参数:
cnt 是灰度图像或轮廓。
返回值:
retval 表示返回的矩形边界的左上角顶点的坐标值及矩形边界的宽度和高度,即x,y,w,h
'''
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt) # 获取轮廓顶点及边长
if w*h<600*600: # 过滤掉小于600*600的矩形框
continue
# print(x,y,w,h) # 570 126 1039 728 左上角x 左上角y 框宽 框高
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),10) # xmin,ymin,xmax,ymax
plt.subplot(2, 2, 2)
plt.title("Gray")
plt.imshow(gray,cmap="gray")
plt.subplot(2, 2, 3)
plt.title("Binary")
plt.imshow(binary,cmap="gray")
plt.subplot(2, 2, 4)
plt.title("result")
plt.imshow(image)
最小包围矩形框(cv2.minAreaRect())
函数 cv2.minAreaRect()能够绘制轮廓的最小包围矩形框。
import numpy as np
import matplotlib.pyplot as plt
import cv2
# 读取图片
img = cv2.imread('2.jpg')
# BGR -> RGB
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(20, 20))
plt.subplot(2, 2, 1)
plt.title("Original")
plt.imshow(image)
# 灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 二值化
ret,binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
'''
retval =cv2.minAreaRect( cnt )
参数:
cnt 是轮廓。
返回值:
retval 表示返回的矩形特征信息,即(最小外接矩形的中心(x,y),(宽度,高度),旋转角度)。
'''
for cnt in contours:
rect = cv2.minAreaRect(cnt) # 获取(最小外接矩形的中心(x,y),(宽度,高度),旋转角度)
if int(rect[1][0])*int(rect[1][1])<600*600:
continue
# print(rect)
# print((int(rect[0][0]-rect[1][0]/2),int(rect[0][1]-rect[1][0]/2)),(int(rect[0][0]+rect[1][0]/2),int(rect[0][1]+rect[1][0]/2)))
cv2.rectangle(image,(int(rect[0][0]-rect[1][0]/2),int(rect[0][1]-rect[1][0]/2)),(int(rect[0][0]+rect[1][0]/2),int(rect[0][1]+rect[1][0]/2)),(255,0,0),10) # xmin,ymin,xmax,ymax
plt.subplot(2, 2, 2)
plt.title("Gray")
plt.imshow(gray,cmap="gray")
plt.subplot(2, 2, 3)
plt.title("Binary")
plt.imshow(binary,cmap="gray")
plt.subplot(2, 2, 4)
plt.title("result")
plt.imshow(image)
最小包围圆形(cv2.minEnclosingCircle())
cv2.minEnclosingCircle()通过迭代算法构造一个对象的面积最小包围圆形。
import numpy as np
import matplotlib.pyplot as plt
import cv2
# 读取图片
img = cv2.imread('2.jpg')
# BGR -> RGB
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(20, 20))
plt.subplot(2, 2, 1)
plt.title("Original")
plt.imshow(image)
# 灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 二值化
ret,binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
'''
center, radius = cv2.minEnclosingCircle( cnt )
参数:
cnt 是轮廓。
返回值:
center 是最小包围圆形的中心。
radius 是最小包围圆形的半径。
'''
for cnt in contours:
(x,y),radius = cv2.minEnclosingCircle(cnt)
if 3.14*radius < 1000: # 过滤掉面积小于1000的圆
continue
center = (int(x),int(y))
radius = int(radius)
cv2.circle(image,center,radius,(255,0,0),10)
plt.subplot(2, 2, 2)
plt.title("Gray")
plt.imshow(gray,cmap="gray")
plt.subplot(2, 2, 3)
plt.title("Binary")
plt.imshow(binary,cmap="gray")
plt.subplot(2, 2, 4)
plt.title("result")
plt.imshow(image)
参考文献
[1] https://opencv.org/
[2] 李立宗. OpenCV轻松入门:面向Python. 北京: 电子工业出版社,2019
- 更多精彩内容,可点击进入
OpenCV-Python快速入门专栏或我的个人主页查看