温馨提示,本文的代码是采用多种方法集成的最优方法
Hello,亲爱的读者们!在这个充满挑战与创新的时代,我们总是不断探索新的技术边界。今天,我非常激动地与大家分享我最近在OpenMV4领域的一次有趣尝试。
作为一名热衷于机器视觉和智能识别的开发者,我一直在寻找能够提升项目性能和准确性的新工具和方法。OpenMV4以其强大的图像处理能力和灵活的编程接口,成为了我探索之旅中的得力助手。
在这篇博客中,我将带领大家一起走进基于色块识别的图形、颜色以及坐标识别的世界。通过一段精心编写的代码,我们可以实现对特定颜色和形状的物体进行快速而准确的识别,而且据我的实际测试,其准确率能够达到90%以上!
不过,请注意,为了获得最佳识别效果,我们需要确保环境光线适宜,并且物体与摄像头保持适当的距离。如果遇到识别效果不佳的情况,您还可以根据实际情况调整代码中的颜色阈值和物体距离参数。
不多说了,让我们直接进入正题,看看这段神奇的代码是如何工作的吧!(友情提示:为了运行这段代码,您需要使用OpenMV IDE。
一、识别矩形(可以将正方形和长方形区别开)
代码部分:
for r in img.find_rects(roi=blob.rect(),threshold=8000):
aspect_ratio = r.w() / r.h() if r.h() != 0 else 0
corners = r.corners()
# 计算矩形的边长
side_lengths = []
for i in range(4):
x1, y1 = corners[i]
x2, y2 = corners[(i + 1) % 4] # 获取下一个角点的坐标
side_length = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) # 计算边长
side_lengths.append(side_length)
# 判断是长方形还是正方形
tolerance = 10 # 定义一个阈值
equal_sides = all(abs(side_lengths[0] - s) < tolerance for s in side_lengths[1:]) # 检查边长是否接近相等
if equal_sides:
x = "b"
else:
x = "d"
解释如下:
-
for r in img.find_rects(roi=blob.rect(),threshold=8000):
- 这行代码使用
img.find_rects
函数来查找图像中所有的矩形区域。roi
参数指定了感兴趣区域(Region of Interest),这里是使用blob.rect()
来定义,即只查找在之前识别到的色块blob
的区域内的矩形。 threshold=8000
是一个阈值参数,用于确定矩形识别的敏感度。数值越小,识别越敏感,但可能会识别到更多的误报。
- 这行代码使用
-
aspect_ratio = r.w() / r.h() if r.h() != 0 else 0
- 这行代码计算当前识别到的矩形的宽高比。
r.w()
和r.h()
分别是矩形的宽度和高度。如果高度不为0,则计算宽高比;如果高度为0(这在实际中不太可能发生,除非矩形的像素点非常少),则宽高比设为0。
- 这行代码计算当前识别到的矩形的宽高比。
-
corners = r.corners()
- 这行代码获取矩形的四个角点的坐标。
corners()
函数返回一个包含四个元组的列表,每个元组包含一个角点的x和y坐标。
- 这行代码获取矩形的四个角点的坐标。
-
side_lengths = []
- 初始化一个空列表,用于存储矩形每条边的长度。
-
接下来的循环
for i in range(4)
-
用于遍历矩形的四个角点。
-
-
x1, y1 = corners[i]
- 这行代码获取当前角点的坐标。
-
x2, y2 = corners[(i + 1) % 4]
- 这行代码获取下一个角点的坐标。使用模运算
(i + 1) % 4
确保当i
为3时,下一个角点是第一个角点,形成一个闭环。
- 这行代码获取下一个角点的坐标。使用模运算
-
side_length = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
- 这行代码计算两个角点之间的距离,即矩形的边长。使用的是欧几里得距离公式。
-
side_lengths.append(side_length)
- 将计算出的边长添加到
side_lengths
列表中。
- 将计算出的边长添加到
-
tolerance = 10
- 定义一个容差值,用于判断边长是否足够接近,从而判断矩形是否为正方形。
-
equal_sides = all(abs(side_lengths[0] - s) < tolerance for s in side_lengths[1:])
- 这行代码使用
all
函数和列表推导式来检查除了第一条边之外的所有边与第一条边的长度差是否都在容差范围内。如果是,说明所有边长都接近相等。
- 这行代码使用
-
if equal_sides:
- 如果所有边长都接近相等,执行下面的代码块。
-
x = "b"
- 将变量
x
设为字符串"b"
,可能表示“box”,即矩形是正方形。
- 将变量
-
x = "d"
- 将变量
x
设为字符串"d"
,可能表示“different”,即矩形是长方形。
- 将变量
二、识别圆形
代码部分:
for c in img.find_circles(threshold=2000, x_margin=2, y_margin=2, r_margin=10, r_min=5, r_max=50, r_step=2):
img.draw_circle(c.x(), c.y(), c.r(), color=(255, 0, 0))
x = "c"
解释如下:
-
img
:-
这是OpenMV相机对象,通常用于图像捕获和处理。
-
-
img.find_circles(...)
:threshold
: 圆形检测的阈值,用于确定哪些边缘点被认为是圆形的一部分。x_margin
: 搜索圆形中心时在x轴方向的边界外延。y_margin
: 搜索圆形中心时在y轴方向的边界外延。r_margin
: 搜索圆形半径时的边界外延。r_min
: 要检测的圆形的最小半径。r_max
: 要检测的圆形的最大半径。r_step
: 半径搜索的步长,即每次迭代增加的半径值。
-
for c in img.find_circles(...)
:-
这是一个for循环,遍历
img.find_circles
函数返回的圆形对象列表。每个c
代表一个检测到的圆形。
-
-
img.draw_circle(c.x(), c.y(), c.r(), color=(255, 0, 0))
:-
color=(255, 0, 0)
: 绘制圆形的颜色,这里指定为红色。 -
c.r()
: 圆形的半径。 -
c.y()
: 圆形中心的y坐标。 -
c.x()
: 圆形中心的x坐标。
-
-
x = "c"
:-
这行代码在上下文中看起来是多余的,因为在for循环中
c
已经被用作表示圆形对象的变量。这可能是一个遗留的代码片段或者是一个错误。
-
三、识别三角形
代码部分:
if 0.4<blob.density()<0.6:
x = "a"
解释如下:
-
if 0.4<blob.density()<0.6:
-
这是一个if语句,用于条件判断。它检查
blob
对象的density()
方法返回的值是否在0.4和0.6之间。这里的blob
很可能是使用OpenMV的图像处理功能检测到的一个图像区域对象。
-
-
blob.density()
:-
这是调用
blob
对象的density()
方法,该方法返回blob的密度。在OpenMV中,blob的密度通常是根据blob的面积和周长计算的,表示blob的形状紧凑程度。密度的计算公式通常是4π * (面积 / 周长^2)
。
-
-
x = "a"
:-
如果条件判断为真,即blob的密度在0.4和0.6之间,那么这行代码将字符串
"a"
赋值给变量x
。这可能是用于标记或分类blob,或者作为后续处理的一部分。
-