OpenCV-Python快速入门(十二):轮廓拟合

前言

  • 本文是个人快速入门OpenCV-Python的电子笔记,由于水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入
    OpenCV-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

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FriendshipT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值