目录
[step4: 显示文字](#step4: 显示文字)
一、不说废话,先上现象
细心的人可以发现第二张图有几个四边形没有被识别到,至于原因下面会给出解释
二、前言
本项目中,我们需要用到上个项目(2-1)中制作的阈值编辑器来对图形的颜色进行阈值提取,便于在代码中进行分割。
三、思路讲解
step1:用阈值编辑器对图像进行处理。
可以发现,对于重叠的图形需要,更加严格限制阈值才能将它们分离开,但是这样又会让掩膜覆盖掉阈值之外的图形。
解决方法是设置多个阈值对图片分割处理,让所有的图形都能够被识别到,最后对处理后的多个图像进行叠加。本文只展现一个阈值的处理,上述思路可自行尝试。
取灰度阈值(0,250)
step2:应用阈值进行二值化
python
# 导入所需的库
import cv2
# 读取输入图像
img = cv2.imread('test3.png')
# 将图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化灰度图像
mask_gray = cv2.inRange(gray, 0, 250)
step3:轮廓查找
python
# 找到轮廓
contours,hierarchy = cv2.findContours(mask_gray, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print("检测到的轮廓数量:",len(contours))
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)
if len(approx) == 4:
img = cv2.drawContours(img, [cnt], -1, (0,170,255), 3)
-
cv2.findContours()
函数用于在二值图像中找到所有轮廓(contours)。cv2.RETR_TREE
:检索所有轮廓,并重构嵌套轮廓的层级关系(即父子关系)。cv2.CHAIN_APPROX_SIMPLE
:只保存轮廓的拐点,从而减少内存使用。contours
:轮廓列表,每个轮廓由一系列点的坐标组成。hierarchy
:层次信息,描述轮廓的嵌套结构。
-
cv2.approxPolyDP()
对轮廓进行多边形拟合,将轮廓点近似为一组直线段:cv2.arcLength(cnt, True)
计算轮廓的周长(曲线长度)。0.01 * cv2.arcLength()
指定多边形拟合精度(越小拟合得越精确)。True
表示轮廓是闭合的。approx
是拟合的多边形轮廓。
-
cv2.drawContours()
函数在原图像上绘制轮廓:img
:目标图像。[cnt]
:轮廓的列表。-1
:绘制所有轮廓点。(0, 170, 255)
:轮廓颜色(BGR格式)。3
:线条的厚度。
step4: 显示文字
python
# 计算三角形质心
M = cv2.moments(cnt)
if M['m00'] != 0.0:
x = int(M['m10']/M['m00'])
y = int(M['m01']/M['m00'])
cv2.putText(img, 'Rectangle', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2)
cv2.putText()
函数在图像的质心位置添加标签"Rectangle":
(x, y)
:标签文本的位置。cv2.FONT_HERSHEY_SIMPLEX
:字体类型。0.6
:字体大小。(0, 0, 0)
:文字颜色。2
:文字的粗细。
四、完整代码贴出
python
# 导入所需的库
import cv2
# 读取输入图像
img = cv2.imread('test3.png')
# 将图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 应用二值化将灰度图像转换为二进制图像
mask_gray = cv2.inRange(gray, 0, 250)
# 找到轮廓
contours,hierarchy = cv2.findContours(mask_gray, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print("检测到的轮廓数量:",len(contours))
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)
if len(approx) == 4:
img = cv2.drawContours(img, [cnt], -1, (0,170,255), 3)
# 计算三角形质心
M = cv2.moments(cnt)
if M['m00'] != 0.0:
x = int(M['m10']/M['m00'])
y = int(M['m01']/M['m00'])
cv2.putText(img, 'Rectangle', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2)
cv2.imshow("mask_gray",mask_gray)
cv2.imshow("Shapes", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
五、现象展示
将此处修改为: if len(approx) == 10:
五角星被识别
六、结语
文章所展示的只是对图像中四边形的识别,若要同时对多个图形进行识别,可以增加多个判断条件"elif len(approx) == 5:" ,大家可以自行尝试。
博文到此结束,写得模糊或者有误之处,欢迎小伙伴留言讨论与批评