文档章节

processing视觉抓取

YANG_G
 YANG_G
发布于 2017/08/28 11:20
字数 1071
阅读 393
收藏 1

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

接之前的scara机械臂,我用processing写了一个简单的视觉抓取小程序:识别红蓝绿色块并顺序抓放。

import processing.serial.*;
import processing.video.*;

Serial Port;
Capture cam;
float[][] kernel ={{0.111,0.111,0.111},
                   {0.111,0.111,0.111},
                   {0.111,0.111,0.111}
                   };//卷积核
//中间像素的灰度值等于周围像素的红色分量减去蓝绿色分量的平均值
//从而使没有红色特征的像素灰度值变为零
//相当于滤镜的效果,修改卷积核的参数,可以达到不一样的效果
int sub_x=0,sub_y=0;//物体中心的像素坐标
float pre_x=0,pre_y=0;//前一帧物体中心的像素坐标
float tar_x=80,tar_y=80;//目标坐标,机械手的坐标
boolean event=false;//坐标计算事件
int c=0;


void setup()//初始化
{
  String portName = Serial.list()[0];
  Port = new Serial(this, portName, 115200);//连接串口
  size(640,480);//屏幕大小
  String[] cameras = Capture.list();
  printArray(cameras);//打印可使用的相机
  cam = new Capture(this, cameras[0]);
  cam.start();//启动相机
  frameRate(30);//帧率
  Port.write("G5 B90\r\n");
  Port.write("G28\r\n");
  Port.write("G1 X80 Y80 Z40\r\n");
  Port.write("G5 B50\r\n");//移动到初始位置
  delay(6000);//延迟,避免摄像头刚打开时的波动
}

void draw()//循环
{
  if (cam.available() == true)
  {
    cam.read();
    image(cam, 0, 0, width, height);
    cam.loadPixels();
    int sum_x=0,sum_y=0;//所有红色像素坐标的和
    int m=1;//红色像素的个数
    for(int y=1;y<cam.height-1;y++)//排除第一行、最后一行、第一列、最后一列像素(这几个地方周围的像素不完整)
    {
      for(int x=1;x<cam.width-1;x++)//经过所有像素
      {
        float sum=0;//最终的灰度值
        for(int ky =-1;ky<=1;ky++)
        {
          for(int kx=-1;kx<=1;kx++)//周围9个像素(包括自身)
          {
          int pos =(y+ky)*cam.width+(x+kx);//将xy坐标换算成pixels[]数组中的位置,pixels[]数组是可以直接调用的储存像素的一维数组(从左到右从上到下)
          int R = (cam.pixels[pos]>> 16) & 0xFF; //取颜色分量,与red()功能相似
          int G = (cam.pixels[pos] >> 8) & 0xFF;
          int B = cam.pixels[pos] & 0xFF;
          float val=0;
          switch(c)//顺序抓取红蓝绿色块
          {
            case 0:
              val =R-1.5*B-1.5*G;
              break;
            case 1:
              val =B-1.5*R-1.5*G;
              break;
            case 2:
              val =G-0.5*B-1*R;
              break;
          }
             //1.5为比例系数,改大可以让红色更突出
          sum +=kernel[ky+1][kx+1]*val;//计算灰度值
          }
        }
        if(sum>0)//新的灰度值非零
        {
          sum_x=sum_x+x;
          sum_y=sum_y+y;//累加坐标
          m=m+1;//计数
        }
       }
     }
   pre_x=sub_x;
   pre_y=sub_y;//前一帧的物体中心
   sub_x=sum_x/m;
   sub_y=sum_y/m;//取平均,计算出物体中心像素坐标
   
   cam.updatePixels();

    fill(#FF0000);
  }
  line(sub_x,0,sub_x,480);
  line(0,sub_y,640,sub_y);//作物体中心的两条交叉线

  if(abs(sub_x-pre_x)<5&&abs(sub_y-pre_y)<5&&sub_x>5&&sub_y>5)//判断是否在移动(波动小于5个像素即为静止),是否存在物体(没有物体时默认为0,为避免波动,这里设置成5)
  {
    if(event==true)//如果物体存在,机械手静止,且事件被触发,则进行计算
    {
     tar_x=tar_x-(0.0625*sub_x-20);
     tar_y=tar_y-(15-0.0625*sub_y);//把像素坐标转化成绝对坐标,根据实际比例
     event=false;//关闭计算事件,即只执行一次计算
     Port.write("G1 X"+tar_x+" Y"+tar_y+"\r\n");//移动到目标位置
     delay(100);//延迟,减小波动
    }
  }
  else //如果机械手在移动,触发计算事件,但不执行计算,为机械手静止时计算做准备
   event=true;
    /*由于机械手的通讯以及动作上有延迟,速度远赶不上摄像头对图像识别的速度,
    所以仅让机械臂在静止时进行一次计算*/
  if(sub_x<5&&sub_y<5)
  {
    if(c<3)
      c=c+1;
     else
       c=0;
  }
  float mx=tar_x;
  float my=tar_y+32;//手抓中心对的坐标,摄像头和手抓有32的y偏移量
  if(sub_x>315&&sub_x<325&&sub_y>235&&sub_y<245)//当物体在画面中心时(+-5个像素)
  { 
     //执行以下动作
     Port.write("G1 X"+mx+'Y'+my+"Z12 F1200\r\n");
     delay(1500);//充分延时
     for(int i=50;i<=150;i+=5)
     {
       Port.write("G5 B"+i+"\r\n");
       delay(50);
     }
     
     delay(500);
     Port.write("G1 Z30\r\n");
     delay(1000);
     switch(c)//顺序摆放红蓝绿色块
     {
       case 0:
         Port.write("G1 X150 Y120\r\n");break;
       case 1:
         Port.write("G1 X150 Y100\r\n");break;
       case 2:
         Port.write("G1 X150 Y80\r\n");break;
     }
     delay(1500);
     Port.write("G1 Z10\r\n");
     delay(500);
     for(int j=150;j>=50;j-=5)
     {
       Port.write("G5 B"+j+"\r\n");
       delay(50);
     }
     delay(500);
     Port.write("G1 X80 Y80 Z40\r\n");
     delay(1500);
    if(c<3)
      c=c+1;
     else
       c=0;
   }
  
  println(tar_x);
  println(tar_y);
}

 

© 著作权归作者所有

上一篇: 三轮全向底盘
YANG_G
粉丝 7
博文 4
码字总数 10801
作品 0
福州
私信 提问
加载中

评论(0)

针对杂乱环境下抓取物体的机器人学习

点击上方“3D视觉工坊”,选择“星标” 干货第一时间送达 作者:脱贫钉子户 https://zhuanlan.zhihu.com/p/98990794 本文仅做学术分享,如有侵权,请联系删除。 摘要 由于障碍物阻碍了可能的...

3D视觉工坊
05/19
0
0
170112-机械臂moveit!抓取

前言 这一节有一点高级了 参考 Mastering ROS 学习记录 使用3D视觉传感器 这是实现抓取任务的基础 注意!传感器可以由Gazebo模拟,也可以直接和物理设备相连传入Gazebo中 确认Gazebo插件正确...

osc_hghvwmhn
2019/07/01
7
0
最前沿:机械臂抓取的落地进展与思考 - 知乎

1 前言 在一年半前,我们已经分析了多家机器人初创公司,特别是面向机械臂抓取的公司。Flood Sung:最前沿:闲谈AI未来及几家学习型机器人初创公司 在更早之前,我们也分析过机器人学习的前沿...

智能单元
05/21
0
0
面向高精度领域的视觉伺服算法汇总

作者:Tom Hardy Date:2020-2-14 来源:面向高精度领域的视觉伺服算法汇总 前言 视觉伺服是工业上很重要的一个领域,在自动装配、高精配准上应用非常多。针对近两年常见的算法模式,在这里进...

Tom Hardy
03/31
0
0
聚焦工业智能化市场,「微链科技」提供高精度、低成本3D机器人视觉解决方案

云栖号资讯:【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 文 | 小妍@边界计划 编辑 | 石亚琼 近年来,伴随着国内工业制造智能化的加速推进,...

云栖号资讯小哥
04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kubernetes Ingress简单入门

本文转载自Rancher Labs 不知道你是否注意到一个奇怪的现象,尽管Kubernetes Ingress API仍然处于beta状态,但是已经有许多公司使用它来暴露Kubernetes服务。从事相关项目的工程师表示,Kub...

osc_slfjdpj6
35分钟前
21
0
ACCDB MDB Explorer for mac(数据库查看器)

想要更加直观的查看大数据,小编推荐使用mac数据查看工具ACCDB MDB Explorer Mac版,该软件能够将导入的数据库导出为XML,XLS,CSV和TXT格式的文件简便高效请添加链接描述,功能强大,需要的...

osc_63i522q0
37分钟前
14
0
二 javanio中的Channel transfer 内容

java nio中channel操作 分散 将channel中读取的数据分散写入多个buffer中 聚集 将多个buffer写入数据到同一个channel 应用 将消息头和消息体放入到不同buffer,便于分类处理应用 将消息头和消...

writeademo
37分钟前
26
0
如何更好的盘活和用好数据资产,企业如何构建数据竞争力的关键在这里!

在今年4月公布的《中共中央国务院关于构建更加完善的要素市场化配置体系机制的意见》中,“数据”首次作为一种新型生产要素写入中央文件中,与土地、劳动力、资本、技术等传统要素并列成为要...

osc_5asswvor
38分钟前
30
0
如何更好的盘活和用好数据资产,企业如何构建数据竞争力的关键在这里!

在今年4月公布的《中共中央国务院关于构建更加完善的要素市场化配置体系机制的意见》中,“数据”首次作为一种新型生产要素写入中央文件中,与土地、劳动力、资本、技术等传统要素并列成为要...

osc_e7clsgkf
39分钟前
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部