Python opencv进行矩形识别

本文介绍如何使用Python的OpenCV库进行矩形识别,详细讲解了高斯模糊、图像格式转换(RGB与HLS)、通道分离、二值化和查找轮廓等关键步骤。通过识别出的矩形顶点,可以计算长边和短边以确定矩形的旋转角度,适用于机器人定位等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python opencv进行矩形识别

图像识别中,圆形和矩形识别是最常用的两种,上一篇讲解了圆形识别,本例讲解矩形识别,最后的结果是可以识别出圆心,4个顶点,如下图:
左边是原始图像,右边是识别结果,在我i5 10400的CPU上,执行时间不到8ms。
在这里插入图片描述
识别出结果后,计算任意3个顶点的彼此距离,共3个数据,其中数值最小值对应的2个顶点是短边,数值最大的2个顶点对应矩形的对角线,中间那个值的矩形的长边。如果是正方形,则最小值和中间值相等。知道了长边的2个点,也就很容易求得矩形的旋转方向,在机器人捡拾物品的过程中,也就知道了末端执行器的旋转角度值。

重要函数讲解

1 高斯模糊

blur = cv2.GaussianBlur(resized, (5, 5), 0)     # 高斯模糊, 窗口为5x5, 标准差为0

高斯模糊,或者叫高斯滤波,其中resized是输入的图像数组,blur是输出的图像数组,(5,5)是一个5*5的卷积核,可大可小,但必须为奇数。这一步是消除图像中的噪声,以免其影响识别结果。

2 图像格式转换

RGB格式

img = cv2.imread(".\\img\\save2.jpg")

图像加载后,默认就是RGB格式。

常见照片的图像格式是RGB或RGBA的,也就是红绿蓝通道,再加上透明度通道。
如果我们要识别的图像中,与颜色有关,如只要识别红色的物体,那我们就用RGB格式进行处理,并提取其中的一个通道。如下图,在红色通道中,红色物体的亮度最高,其他同理。
但是显然,下图中,在红色通道要提取红色并不容易,因为红色通道中红色和背景的颜色差不多,难以将前景与背景分离。而绿色通道和蓝色通道,对红色的识别度更好些。
在这里插入图片描述

HLS格式

lab = cv2.cvtColor(blur, cv2.COLOR_RGB2HLS)     # 转为HLS图像模式, 此模式区分颜色简单, 同时处理速度快

如果与颜色无关,需要识别时,可以考虑采用HLS色彩模式进行。这个色彩模型是由色调,饱和度,亮度3个通道构成,如下:
在这里插入图片描述
可以看出,L通道的轮廓最明显,因此可以使用该通道来做图像识别。

同样对于需要提取的红色物体,可以在识别出矩形之后,取矩形中心点(更好的是中心一小块区域的平均值)的颜色值,再自己判断一下颜色,即可筛选出想要的红色矩形了。

3 通道分离

这其实是对numpy数组的操作

channel_h = lab[:, :, 0]                        # 提取H通道 色相
channel_l = lab[:, :, 1]                        # 提取L通道 明度
channel_s = lab[:, :, 2]                        # 提取S通道 饱和度

4 二值化

ret_val, bin_channel_l = cv2.threshold(channel_l.copy(), 170, 255, cv2.THRESH_BINARY_INV)   # 复制L通道, 并二值化

第1个参数是复制一次L通道
第2个参数:170 是阈值
第3个参数:255 是填充值
第4个参数是模式,即二值化,还是反二值化,本例是反二值化

5 查找轮廓

    contours = cv2.findContours(bin_channel_l, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

第1个参数是图像数组
第2个参数是查找模式,当前模式为查找最外面的轮廓,对于轮廓内部的轮廓,则不查找
第3个参数是输出所有轮廓点的信息

查找的轮廓点会有很多组,面积大小也不一,本例中只关心4个顶点的轮廓,也就是矩形。

面积大小可以设一个阈值,小于这个阈值的矩形也不是我们想要的。根据矩形长宽所占用的像素值,乘一下就是该矩形的面积,超过这个阈值的矩形,就是我们想要的。

最后,如果要对颜色进行筛选,则可以从矩形的中心取一个5x5的矩形,对其RGB的值分别进行求和,再除以25(5x5),即是该区域的颜色值。

完整代码

将以下代码复制到IDE中即可,需要事先安装好python, opencv, numpy等相关运行库

# coding:   UTF-8
# 作者:     李佳
# Email:    [email protected]
# WeChat:   laolidesenlin
# Date:    2020/4/1  20:09
# Filename:detect_rect.PY
# SoftTool:PyCharm
__author__ = '李佳'


import cv2
import time
import numpy as np


def draw_rect(img, rect_point):
    cv2.line(img, rect_point[0], rect_point[1]
<think>我们被要求回答关于Python OpenCV矩形识别的问题,并参考了提供的引用内容。引用[1]和[2]提供了矩形识别的基本步骤和代码示例,引用[3]提供了绘制矩形的方法,引用[4]提到了OCR,但这个问题主要是关于矩形识别,因此我们主要参考引用[1][2][3]。 根据引用[2],矩形识别的基本步骤包括: 1. 读取图像 2. 转换为灰度图像 3. 边缘检测(如Canny) 4. 查找轮廓 5. 遍历轮廓,对每个轮廓进行多边形近似,如果近似后的顶点数为4,则认为是矩形 6. 绘制矩形轮廓 此外,引用[3]提供了绘制矩形的具体函数:`cv2.rectangle`,但注意在轮廓绘制时,我们也可以使用`cv2.drawContours`来绘制轮廓。 我们将按照以下步骤进行: 1. 导入必要的库(OpenCV和NumPy) 2. 读取图像 3. 转换为灰度图像 4. 进行边缘检测(Canny边缘检测) 5. 查找轮廓(注意OpenCV版本不同,`cv2.findContours`的返回值格式可能不同,我们使用OpenCV4的写法) 6. 遍历轮廓,对每个轮廓进行多边形近似,并判断是否为矩形(4个顶点) 7. 为了更精确,我们还可以通过面积、长宽比等进一步筛选 8. 绘制检测到的矩形 9. 显示结果 下面是一个完整的示例代码,并附有详细注释:</think>以下是使用 Python OpenCV 进行矩形识别的完整教程和示例代码,包含核心步骤和优化技巧: ### 一、矩形识别基础步骤 1. **图像预处理** - 灰度转换减少计算量:$ \text{gray} = 0.299R + 0.587G + 0.114B $ - 高斯滤波降噪:$ G(x,y) = \frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}} $ - 边缘检测(Canny算法) 2. **轮廓检测** 使用轮廓近似法识别多边形,通过顶点数筛选矩形(4个顶点) 3. **几何验证** - 角度验证:内角接近 $90^\circ$(容差±15°) - 长宽比验证:$ \text{ratio} = \frac{\text{width}}{\text{height}} $ ### 二、完整示例代码 ```python import cv2 import numpy as np # 1. 读取图像 image = cv2.imread('rectangles.jpg') orig = image.copy() # 2. 预处理 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blurred, 50, 150) # 3. 轮廓检测 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # 4. 轮廓近似 peri = cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, 0.02 * peri, True) # 5. 矩形验证 (4个顶点 + 凸多边形) if len(approx) == 4 and cv2.isContourConvex(approx): # 6. 计算旋转矩形 rect = cv2.minAreaRect(contour) box = cv2.boxPoints(rect) box = np.int0(box) # 7. 绘制结果 cv2.drawContours(image, [box], 0, (0, 255, 0), 2) # 8. 计算中心点 (矩特征) M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.circle(image, (cX, cY), 5, (255, 0, 0), -1) # 9. 显示结果 cv2.imshow("Original", orig) cv2.imshow("Edge Detection", edges) cv2.imshow("Rectangles Detected", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` ### 三、关键函数说明 1. `cv2.approxPolyDP()`:轮廓多边形近似 - `0.02 * peri`:近似精度参数(值越小越精确) 2. `cv2.minAreaRect()`:计算最小外接旋转矩形 - 返回旋转角度信息:$ \theta \in [-90^\circ, 0^\circ] $ 3. `cv2.moments()`:计算轮廓矩 - 中心点公式:$ cX = \frac{M_{10}}{M_{00}}, cY = \frac{M_{01}}{M_{00}} $ ### 四、优化技巧 1. **光照不均处理** ```python lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB) l, a, b = cv2.split(lab) clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8)) l_clahe = clahe.apply(l) ``` 2. **透视校正**(提取矩形内容) ```python # 定义源点和目标点 src_pts = approx.reshape(4, 2) dst_pts = np.array([[0,0], [500,0], [500,300], [0,300]], dtype="float32") # 计算透视变换矩阵 M = cv2.getPerspectiveTransform(src_pts, dst_pts) warped = cv2.warpPerspective(orig, M, (500, 300)) ``` 3. **深度学习辅助**(复杂场景) ```python # 使用YOLO等模型进行初步检测 net = cv2.dnn.readNet("yolov4.weights", "yolov4.cfg") blob = cv2.dnn.blobFromImage(image, 1/255, (416,416)) net.setInput(blob) outputs = net.forward(net.getUnconnectedOutLayersNames()) ``` ### 五、常见问题解决 - **重叠矩形**:使用NMS(非极大值抑制) - **部分遮挡**:结合Hough直线检测 - **曲面变形**:增大`approxPolyDP`的容差系数 > 提示:实际应用中建议结合场景调整Canny阈值和近似精度参数[^2],工业检测场景可添加形态学操作增强边缘[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

老李的森林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值