便宜、能用。场景是从桌面抓零件放进模具槽,精度要求不高,±2mm都能接受。但机械臂用久了有累积误差,放不到准确位置。

一、项目背景:要便宜,也要能“看得见”

想做个机械臂抓取平台,预算有限。核心需求:

  1. 能识别桌面上随机位置的小零件(金属块)

  2. 能准确放入模具槽(槽宽比零件大3mm)

  3. 总成本控制在1.5万以内(含机械臂)

用不起激光雷达,也上不了深度相机。最后方案:普通摄像头做识别,二维码做二次定位补偿

二、三步走:识别→抓取→精放

第一步:先教相机认识零件

# 伪代码 - 采集模板
def teach_template():
    相机拍照("空桌面")
    把零件放在桌面明显位置
    相机拍照("有零件的桌面")
    
    # 简单粗暴:背景差分
    干净背景 = 读取("空桌面.jpg")
    当前画面 = 读取("有零件的桌面.jpg")
    
    # 扣出零件轮廓
    差分图 = 当前画面 - 干净背景
    二值化图 = cv2.threshold(差分图, 30, 255, 二值化)
    
    # 找到最大轮廓就是零件
    轮廓列表 = cv2.findContours(二值化图)
    零件轮廓 = 取面积最大的轮廓(轮廓列表)
    
    # 保存为模板
    模板 = 从当前画面裁剪(零件轮廓的外接矩形)
    保存图片(模板, "零件模板.png")
    
    print("教学完成!模板已保存")

第二步:识别并抓取

# 伪代码 - 识别抓取
def pick_and_place():
    # 机械臂移到拍照位(固定高度)
    机械臂.move_to([x=200, y=200, z=300])
    
    while True:
        # 拍照识别
        当前图像 = 相机.拍照()
        
        # 用模板匹配找零件
        匹配结果 = cv2.matchTemplate(当前图像, 模板图片)
        最小值, 最大值, 最小位置, 最大位置 = cv2.minMaxLoc(匹配结果)
        
        if 最大值 < 0.7:  # 匹配度阈值
            print("没找到零件,换个位置拍")
            机械臂.move_to(随机位置())
            continue
            
        # 计算零件中心像素坐标
        零件中心x = 最大位置.x + 模板宽度/2
        零件中心y = 最大位置.y + 模板高度/2
        
        # 像素坐标转机械臂坐标(需要标定)
        实际坐标 = 像素转世界坐标(零件中心x, 零件中心y)
        
        # 计算抓取角度(简单版:用外接矩形角度)
        矩形 = cv2.minAreaRect(零件轮廓)
        旋转角度 = 矩形[2]  # 得到-90~0度的角度
        
        # 执行抓取
        机械臂.move_to([实际坐标.x, 实际坐标.y, 300])  # 先到上方
        机械臂.旋转夹具(旋转角度)  # 调整角度
        机械臂.move_to([实际坐标.x, 实际坐标.y, 50])   # 下降
        气动夹爪.闭合()
        机械臂.move_to([实际坐标.x, 实际坐标.y, 300])  # 抬起
        
        break

这里有个关键:我们的摄像头是固定安装的,不是装在机械臂上的“手眼”。这样便宜,但需要做一次手眼标定——让机械臂走几个点,建立像素坐标和世界坐标的对应关系。

第三步:二维码辅助精准放置

机械臂用久了会有累积误差,直接按坐标放可能偏。我们在模具槽左边贴了个二维码。

# 伪代码 - 二维码定位补偿
def precise_place():
    # 先到大致的放置位置
    理论放置点 = [x=400, y=300, z=300]
    机械臂.move_to(理论放置点)
    
    # 拍照找二维码
    当前图像 = 相机.拍照()
    二维码信息, 二维码坐标 = cv2.QRCodeDetector().detectAndDecode(当前图像)
    
    if 二维码坐标 is not None:
        # 计算二维码中心
        二维码中心 = 计算中心点(二维码坐标)
        
        # 二维码的实际坐标我们是知道的(贴的时候测量过)
        二维码理论像素坐标 = [320, 240]  # 相机分辨率640x480时的中心
        二维码实际世界坐标 = [395, 295, 0]  # 机械臂坐标系下的位置
        
        # 计算偏差
        像素偏差x = 二维码中心.x - 二维码理论像素坐标[0]
        像素偏差y = 二维码中心.y - 二维码理论像素坐标[1]
        
        # 像素偏差转世界偏差(标定时得到的比例)
        世界偏差x = 像素偏差x * 0.1  # 1像素=0.1mm
        世界偏差y = 像素偏差y * 0.1
        
        # 修正放置位置
        实际放置点 = [
            理论放置点[0] - 世界偏差x,
            理论放置点[1] - 世界偏差y,
            理论放置点[2]
        ]
        
        print(f"检测到偏差:X偏{世界偏差x:.1f}mm, Y偏{世界偏差y:.1f}mm")
        
    # 执行放置
    机械臂.move_to([实际放置点[0], 实际放置点[1], 300])
    机械臂.move_to([实际放置点[0], 实际放置点[1], 30])  # 下降到槽内
    气动夹爪.松开()
    机械臂.move_to([实际放置点[0], 实际放置点[1], 300])  # 抬起​

二维码的妙用:每次放置前都看一眼二维码,就知道机械臂现在“跑偏”了多少,实时补偿。相当于给机械臂装了个“定期校准”功能。

如果你也想做低成本视觉引导,记住这几点:

  1. 能固定相机就别用手眼——固定安装标定简单,稳定性好

  2. 背景越简单越好——一块纯色桌布能解决80%识别问题

  3. 二维码是穷人的补偿方案——贴几个二维码,定期看一眼,精度能提升不少

  4. 别追求完美——低预算就是做取舍,先实现功能再优化

这个项目虽然“低配”,但很典型——很多中小厂的第一步自动化就是这样:用成熟便宜的技术,解决实际的小问题。我们做技术外包的,经常就是帮客户在这种“有限条件”下做出“能用就行”的方案。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐