激光SLAM-地图边界噪点的处理(地图的美化)--图像处理的方法

激光SLAM-地图边界噪点的处理(地图的美化)--图像处理的方法

问题介绍

本问是实际扫地机器人对于2D激光SLAM采用cartographer所建的地图中,可以看到边缘处有噪点,从而影响了地图在app端的图片效果,针对这个问题,产生了两种解决的思路:
激光建图中存在的边缘噪声
方法一:直接从建图的图片入手,运用数字图像处理的方法处理地图。
方法二:从cartographer源码处优化边缘的噪点,对噪点进行剔除。
本文主要采用了方法一,并随研究更新,同时学习开始研究方法二的实现。

实现步骤

  1. 图片输入为三通道RGB图,首先进行图片灰度化处理 ;
  2. 对灰度图像(单通道)进行高斯滤波,滤波后的模糊图片;
  3. 对滤波后的图片采用canny算子进行边缘检测
  4. 检测后图像恢复3通道,并显示在原图像中;
  5. 阈值判断,以边缘为分界,边缘处更新相关灰度,边缘外的噪点与原地图外的灰度保持一致,其余灰度不变;

代码实现

#include <iostream>
#include <chrono>
using namespace std;

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main ( int argc, char** argv )
{
    // 读取argv[1]指定的图像
    cv::Mat image;
    image = cv::imread ( "/home/figure.pgm" ); //cv::imread函数读取指定路径下的图像
    // 判断图像文件是否正确读取
    if ( image.data == nullptr ) //数据不存在,可能是文件不存在
    {
        cerr<<"文件"<<argv[1]<<"不存在."<<endl;
        return 0;
    }
    
    // 文件顺利读取, 首先输出一些基本信息,图像尺度信息
    cout<<"原图像宽为"<<image.cols<<",高为"<<image.rows<<",通道数为"<<image.channels()<<endl;
    cv::imshow ( "image", image );      // 用cv::imshow显示图像
    cv::waitKey ( 0 );                  // 暂停程序,等待一个按键输入

    //1.灰度图转换,默认的色彩空间是BGR
    cv::Mat srcGray;
    cvtColor(image, srcGray, CV_BGR2GRAY);
    imshow("srcGray", srcGray);
    cout<<"灰度图像宽为"<<srcGray.cols<<",高为"<<srcGray.rows<<",通道数为"<<srcGray.channels()<<endl;
    cv::waitKey ( 0 );                  // 暂停程序,等待一个按键输入

    //2.对灰度图像进行高斯滤波
    cv::Mat Gaus3_image;
    GaussianBlur(srcGray,Gaus3_image,Size(3,3),2);
    imshow("Gaus3_image",Gaus3_image);
    cout<<"高斯滤波图像宽为"<<Gaus3_image.cols<<",高为"<<Gaus3_image.rows<<",通道数为"<<Gaus3_image.channels()<<endl;
    cv::waitKey ( 0 );                  // 暂停程序,等待一个按键输入

    //3.canny算子检测边缘
    cv::Mat Can_image;
    std::vector<Vec4i> lines; //定义数组获取直线
    cv::Canny(Gaus3_image,Can_image,200,350);
    imshow("srcGray_line",Can_image);
    cout<<"canny算子提线图像宽为"<<Can_image.cols<<",高为"<<Can_image.rows<<",通道数为"<<Can_image.channels()<<endl;
    cv::waitKey ( 0 );

    // 4.检测后图像恢复3通道,并显示在原图像中
    cv::Mat dst,image1;
    dst = Scalar::all(0);
    image1 = image.clone();
    image1.copyTo(dst,Can_image);
    imshow("image_line",dst);
    cv::waitKey ( 0 );

    cv::Mat image2;
    image2 = image-dst;
    imshow("image2",image2);
    cv::waitKey ( 0 );

    // 5.遍历图片,阈值判断
    for ( int i = 0; i < image2.rows; i++ )
    {
        for ( int j=0; j<image2.cols; j++ )
        {
            if(image2.at<Vec3b>(i,j)[0]==image2.at<Vec3b>(i,j)[1] && image2.at<Vec3b>(i,j)[0]==image2.at<Vec3b>(i,j)[2])
            {
                if(image2.at<Vec3b>(i,j)[0]>=0 && image2.at<Vec3b>(i,j)[0]<=55)
                    image2.at<Vec3b>(i,j)[0]=image2.at<Vec3b>(i,j)[1]=image2.at<Vec3b>(i,j)[2]=0;
                else if(image2.at<Vec3b>(i,j)[0]>55 && image2.at<Vec3b>(i,j)[0]<170)
                    image2.at<Vec3b>(i,j)[0]=image2.at<Vec3b>(i,j)[1]=image2.at<Vec3b>(i,j)[2]=128;
                else
                    image2.at<Vec3b>(i,j)[0]=image2.at<Vec3b>(i,j)[1]=image2.at<Vec3b>(i,j)[2];
            }
        }
    }
    imshow("image3",image2);
    cout<<"imag2_f"<<Can_image.cols<<endl;
    cv::waitKey ( 0 );



    cv::destroyAllWindows();
    return 0;
}

效果

left:原图像 right:最终图像

参考文章

canny边缘检测
[1]:https://blog.csdn.net/zhmxy555/article/details/25560901
[2]:https://blog.csdn.net/qq78442761/article/details/54313569
[3]:https://blog.csdn.net/weicao1990/article/details/54570903
[4]:https://blog.csdn.net/MoreWindows/article/details/8239625
霍夫变换检测直线
[5]:https://blog.csdn.net/viewcode/article/details/8090932
[6]:https://cloud.tencent.com/developer/article/1470624
[7]:https://www.geek-share.com/detail/2713436600.html
[8]:https://blog.csdn.net/hzq20081121107/article/details/9287941
高斯滤波
[9]:https://www.cnblogs.com/hugochen1024/p/12864055.html#%E5%8F%8C%E8%BE%B9%E6%BB%A4%E6%B3%A2bilateral-filter
[10]:视觉SLAM十四讲5讲
[11]:思岚科技https://www.slamtec.com/en/News/Detail/389
[12]:思岚科技https://zhuanlan.zhihu.com/p/35202710

  • 6
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值