C++ 如何使用OpenCV和PCL在二维平面上投影红外图像

C++ 如何使用OpenCV和PCL在二维平面上投影红外图像,c++,algorithm,opencv,image-processing,computer-vision,C++,Algorithm,Opencv,Image Processing,Computer Vision,我有一个Kinect,我正在使用OpenCV和点云库。我想将IR图像投影到2D平面上,用于叉车托盘检测。我该怎么做 我正在尝试检测叉车中的托盘,这里有一个图像:RGB数据在哪里?您可以使用它来帮助检测。不需要将图像投影到任何平面上即可检测小球。基本上有两种检测方法 基于神经网络、模糊逻辑、机器学习等的非确定性 这种方法需要一个训练数据集来识别对象。正确的训练集和分类器结构/拓扑选择需要大量的经验。但除此之外,您不需要对其进行编程。。。通常使用一些现成的库/工具来配置和传递数据 基于距离或相关系数

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


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

RGB数据在哪里?您可以使用它来帮助检测。不需要将图像投影到任何平面上即可检测小球。基本上有两种检测方法

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

    这种方法需要一个训练数据集来识别对象。正确的训练集和分类器结构/拓扑选择需要大量的经验。但除此之外,您不需要对其进行编程。。。通常使用一些现成的库/工具来配置和传递数据

  • 基于距离或相关系数的确定性

    我将从检测特定功能开始,如:

    • 托盘具有特定尺寸
    • 托盘有锋利的边缘和特定的几何图形形状深度数据
    • 托盘具有特定的颜色范围(黄色木材+/-照明和污垢)
    • 木材有特定的纹理图案
    因此,为每个特征计算一些系数,比如物体与真实物体的距离。然后将所有系数的距离加三倍(可能是加权的,因为某些特征更稳健)

  • 我不使用#1方法,因此我选择#2。因此,结合RGB和深度数据(它们必须精确匹配)。然后分割图像(基于深度和颜色)。之后,对每个找到的对象进行分类,如果它是托盘

    [Edit1]

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

    你可以看到它有多差,所以我怀疑你是否可以使用深度数据进行检测

    顺便说一句,我用我的眼睛来观察

    剩下的就是彩色图像,只检测颜色匹配的区域。然后对特征进行检测和分类。图像中托盘的颜色几乎为白色。这里HSV将颜色减少为基本16色(太懒了,无法分割)

    您应该通过设置获得托盘可能的颜色范围,以便于检测。然后检查这些物体的特征,如大小、形状、面积、周长

    [Edit2]

    因此我将从图像预处理开始:

  • 转换为HSV
  • t仅显示接近托盘颜色的像素

    我选择了
    (H=40,S=18,V>100)
    作为托盘颜色。我的HSV范围是每个通道的
    ,因此
    色调
    角度差只能是
    最大值,它对应于我的范围内的

  • 去除过薄区域

    只需扫描所有水平线和垂直线,计算后续设置的像素数,如果太小,请将其恢复为黑色

  • 结果是:

    左边的原始图像(缩小到它适合这个页面),中间是颜色tRESHORD结果,最后是小区域的过滤。您可以使用Treshold和托盘颜色来改变行为以满足您的需要

    这里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;
    
    int tr_d=10;//托盘的最小尺寸[像素][
    整数h,s,v,x,y,xx;
    颜色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;
    //[颜色选择]
    对于(y=0;yDraw(xx,0,pic1.bmp);xx+=pic1.xs;
    //[去除过薄区域]
    
    对于(y=0;y@Raluca如果我有来自深度图的红外图像和点云,我将如何识别托盘?抱歉,但我仍然不明白。你想将该图像投影到一个平面上?如果是,哪个平面?或者你想将点云投影到该图像上?是的,我想将点云投影到该图像上如果你的目标是检测托盘,wh你不使用机器学习吗?OpenCV有这样的算法。你需要一个数据库,其中包含带托盘和不带托盘的图像,并进行相应的标记。你能指导我使用OpenCV机器学习算法吗?我有一个点云转换为高度图,我有一组3D数据。我已经添加了RGB图像和深度图像。你可以吗请写一个伪代码或方法2的opencv代码,以帮助我更多。我不知道如何正确地做。请我需要帮助:)@andre added edit…具体需要什么帮助(我不使用opencv,所以我不能在其中写代码)所以你把图像转换成了HSV?接下来我该怎么做?我该如何检测尺寸、形状和面积?我应该用FindContetors提取托盘吗?你能分割它并给出一个例子吗?甚至用伪代码来实现我自己的算法