项目概述
为实现工业场景下,金属U型弯管缺陷的自动化检测,基于RT-Thread VisionBoard开发板设计了一款弯管铜环检测设备,检测U型铜弯管两端的铜环是否安装正常。
设计思路
本项目基于RT-Thread VisionBoard开发板,使用openmv机器视觉框架,对获取工件图片进行形态学操作,获取工件尺寸和角度,并将各个工件在图片中分割出来,并对工件中铜环的位置进行检测,获取铜环相对工件位置,最终计算工件是否合格。

系统说明
- 系统硬件
- 系统使用的技术要点
- 主控模块基于RT-Thread 软件架构设计
- 开发软件: RT-Studio ,OpenMV IDE
- 开发语言: C语言、Python
设计过程
本次设计的主要功能为识别铜环相对工件位置,判断工件是否合格。
RA8 Vision Board 开发板支持OPENMV开发框架,可以方便的进行一些简易的机器视觉任务开发。
- 图像的采集:在本次设计中,我们通过RA8 Vision Board 开发板板载的摄像头模块采集工件图像,为确保图像质量稳定以及方便使用OPEMMV的目标检测相关API,我们设置图片格式为RGB565,图像尺寸为QVGA ( 320 X 240 ) ,关闭白平衡和自动增益。
- 工件的分割与定位:使用OpenMV IDE的阙值编辑器获取图像最佳参考阙值,并使用OPENMV的目标检测相关API对采集图像进行阙值分割,设置最小分割像素大小,过滤干扰。分割后生成的四个角点相对工件的位置不固定,不利于后续处理,需要对角点进行重新排序,确保角点顺序相对工件姿态一致。
- 铜环相对位置定位:在获取工件的位置、尺寸和角度后,沿工件最小外接矩形框的窄边进行搜索,并对搜索到的所有点进行聚类,获取铜环相对工件的位置,判断工件是否合格。
系统功能介绍
通过摄像头采集U型铜弯管图像,识别出工件的位置尺寸和角度,并获取两端铜环相对弯管位置,最终计算工件是否合格。

工程代码
导入相关模块
import sensor
import time
import math
初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
对四个角点进行排序,确保角点顺序相对工件姿态一致
# 计算两点之间的欧几里得距离
def distance(p1, p2):
return math.sqrt((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2)
# 对角点排序,确保第一个和第二个点位于矩形的长边
def sort_corners(p1, p2, p3, p4, center):
# 创建一个角点列表
corners = [p1, p2, p3, p4]
pp1=p1
pp2=p2
pp3=p3
pp4=p4
# 计算四个点之间的距离,存储在一个列表中
if(distance(p1, p2)-distance(p2, p3))<0:
# corners = [p2, p3, p4, p1]
pp1=p2
pp2=p3
pp3=p4
pp4=p1
if(distance(pp1,center)-distance(pp4,center)>0):
corners = [pp3, pp4, pp1, pp2]
else:
corners = [pp1, pp2, pp3, pp4]
return corners
生成内缩后的新角点
def shrink_point(point,center,pixel=1):
# 将元组转换为列表
point_tmp = list(point)
if point[0]-center[0]>0:
point_tmp[0]=point[0]-pixel
else:
point_tmp[0]=point[0]+pixel
if point[1]-center[1]>0:
point_tmp[1]=point[1]-pixel
else:
point_tmp[1]=point[1]+pixel
# 返回新的角点,转换回元组
return tuple(point_tmp)
# 生成内缩后的新角点
def shrink_rectangle(p1, p2, p3, p4,center):
pp1=shrink_point(p1,center)
pp2=shrink_point(p2,center)
pp3=shrink_point(p3,center)
pp4=shrink_point(p4,center)
cornersp = [pp1, pp2, pp3, pp4]
# 返回新角点
return cornersp
通过阙值分割各个工件
img = sensor.snapshot()
for blob in img.find_blobs(
[thresholds[threshold_index]],
pixels_threshold=600,
area_threshold=600,
merge=True,
):
获取铜环相对工件位置
myblod=sort_corners(blob.min_corners()[0],blob.min_corners()[1],blob.min_corners()[2],blob.min_corners()[3],(blob.cx(), blob.cy()))
imgx=img.binary([red_threshold],copy=True)
myblod = shrink_rectangle(myblod[0], myblod[1], myblod[2], myblod[3],(blob.cx(), blob.cy()))
l1=find_black_pixel_along_edge(interpolate_line(myblod[0], myblod[3]))
l2=find_black_pixel_along_edge(interpolate_line(myblod[1], myblod[2]))