gpt4 book ai didi

c++ - 如何使用OpenCV和PCL在2D平面上投影红外图像

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:57:31 28 4
gpt4 key购买 nike

我有一个 Kinect ,并且正在使用 OpenCV 和点云库。我想将 IR 图像投影到 2D 平面上,以检测叉车货盘。我该怎么做?

我正在尝试检测叉车中的托盘,这是一个图像:

最佳答案

RGB 数据在哪里?您可以使用它来帮助进行检测。您无需将图像投影到任何平面上即可检测出颗粒。基本上有两种检测方法

  • 基于神经网络,模糊逻辑,机器学习等的不确定性

    这种方法需要训练数据集来识别对象。正确的训练集和分类器架构/拓 flutter 选择需要大量经验。但是除此之外,您不需要对其进行编程...通常通常使用一些易于使用的lib / tool来配置和传递数据。
  • 基于距离或相关系数的确定性

    我将从检测以下特定功能开始:
  • 托盘具有特定大小
  • 托盘在深度数据
  • 中具有锋利的边缘和 特定的几何形状形状
  • 托盘具有特定颜色范围(淡黄色木材+/-灯光和污垢)
  • 木材具有特定的纹理图案

  • 因此,为每个特征计算一些系数,即对象与实际货盘之间的距离。然后只需将所有系数的距离取整(可能会加权,因为某些功能更强大)。
    我不使用 #1 方法,所以我会选择 #2 。因此,将 RGB 和深度数据结合在一起(必须精确匹配)。然后分割图像(基于深度和颜色)。之后,为每个找到的对象分类是否是托盘...

    [Edit1]

    您的彩色图像与深度数据不对应。对齐的灰度质量差,深度数据图像也很差。深度数据是否以某种方式处理(精度降低)?如果您从不同 Angular 查看数据:

    image

    您可以看到它有多穷,所以我怀疑您是否可以完全使用深度数据进行检测...

    PS。我将 Align already captured rgb and depth images用于可视化。

    剩下的唯一是彩色图像,并仅检测具有匹配颜色的区域。然后检测特征并分类。图像中托盘的颜色几乎是白色的。 HSV在这里将颜色减少为基本的16种颜色(太懒而无法分割)

    color reduction

    您应该通过设置获得可能的托盘颜色范围,以简化检测。然后检查这些对象的尺寸,形状,面积,周长等特征。

    [Edit2]

    ,所以我将从图像预处理开始:
  • 转换为HSV
  • 仅限制接近调色板颜色的像素

    我选择(H=40,S=18,V>100)作为货盘颜色。我的HSV范围是每个通道<0,255>,因此Hue Angular 差只能是<-180deg,+180deg> max,它对应于我的范围中的<-128,+128>
  • 删除太薄的区域

    只需扫描所有“水平”和“垂直”线即可计算随后设置的像素,如果尺寸太小,则将它们重新着色为黑色...

  • 结果如下:

    example1

    左侧是原始图像(缩小后的尺寸使其适合此页面),中间是颜色阈值结果,最后是对小区域的过滤。您可以使用阈值和货盘颜色来改变行为,以适应您的需求。

    这里 C++ 代码:
    int tr_d=10;    // min size of pallet [pixels[
    int h,s,v,x,y,xx;
    color c;

    pic1=pic0;
    pic1.pf=_pf_rgba;
    pic2.resize(pic1.xs*3,pic1.ys); xx=0;
    pic2.bmp->Canvas->Draw(xx,0,pic0.bmp); xx+=pic1.xs;

    // [color selection]
    for (y=0;y<pic1.ys;y++)
    for (x=0;x<pic1.xs;x++)
    {
    // get color from image
    c=pic0.p[y][x];
    rgb2hsv(c);
    // distance to white-yellowish color in HSV (H=40,S=18,V>100)
    h=c.db[picture::_h]-40;
    s=c.db[picture::_s]-18;
    v=c.db[picture::_v];
    // hue is cyclic angular so use only shorter angle
    if (h<-128) h+=256;
    if (h>+128) h-=256;
    // abs value
    if (h< 0) h=-h;
    if (s< 0) s=-s;
    // treshold close colors
    c.dd=0;
    if (h<25)
    if (s<25)
    if (v>100)
    c.dd=0x00FFFFFF;
    pic1.p[y][x]=c;
    }
    pic2.bmp->Canvas->Draw(xx,0,pic1.bmp); xx+=pic1.xs;

    // [remove too thin areas]
    for (y=0;y<pic1.ys;y++)
    for (x=0;x<pic1.xs;)
    {
    for ( ;x<pic1.xs;x++) if ( pic1.p[y][x].dd) break; // find set pixel
    for (h=x;x<pic1.xs;x++) if (!pic1.p[y][x].dd) break; // find unset pixel
    if (x-h<tr_d) for (;h<x;h++) pic1.p[y][h].dd=0; // if too small size recolor to zero
    }
    for (x=0;x<pic1.xs;x++)
    for (y=0;y<pic1.ys;)
    {
    for ( ;y<pic1.ys;y++) if ( pic1.p[y][x].dd) break; // find set pixel
    for (h=y;y<pic1.ys;y++) if (!pic1.p[y][x].dd) break; // find unset pixel
    if (y-h<tr_d) for (;h<y;h++) pic1.p[h][x].dd=0; // if too small size recolor to zero
    }
    pic2.bmp->Canvas->Draw(xx,0,pic1.bmp); xx+=pic1.xs;

    有关 picturecolor的描述,请参见 how to extract the borders of an image (OCT/retinal scan image)。或查看我的任何 DIP / CV 标记的答案。现在,该代码已被很好地注释并且很简单,但是只需添加:

    您可以忽略 pic2东西,它只是上面发布的图像,因此我不需要手动打印屏幕并合并油漆中的子结果...为了提高鲁棒性,您应该添加动态范围的增强(因此,阈值对于任何情况都具有相同的条件输入图像)。另外,您应该比较的不仅仅是单色(如果存在更多的木质托盘类型)。

    现在,您应该对区域进行细分或标记
  • 遍历整个图像
  • 查找具有托盘颜色
  • 的第一个像素集
  • 用与设置的托盘颜色不同的一些不同的ID颜色填充区域

    我使用黑色0x00000000空间和白色0x00FFFFFF作为调色板像素颜色。因此,请使用ID={1,2,3,4,5...}。另外,请记住填充像素的数量(即您的面积),因此您无需再次计算。您也可以在填充时直接计算边界框。
  • 计算和比较功能

    您需要尝试一张以上的图像。找出哪些属性适合检测。我会考虑周长与面积之比。和或边界框大小...可以通过简单地选择所有具有正确ID颜色的相邻黑色像素的像素来提取周长。

  • 另请参见类似的 Fracture detection in hand using image proccessing

    祝好运并玩得开心点 ...

    关于c++ - 如何使用OpenCV和PCL在2D平面上投影红外图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37972263/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com