专栏首页行走的机械人唉,再再再学一下直方图:直方图反投影

唉,再再再学一下直方图:直方图反投影

点击上方"蓝色小字"关注我哦

之前写过一篇【opencv】带你再学一遍直方图,里面的内容可以看下图。所以今天还要再再再学一个直方图的API:直方图反投影。

直方图反向投影是干啥的呢,它用于图像分割或在图像中查找感兴趣的对象。用什么来查找呢?用直方图。

直方图在一定程度上可以反应图像的特征,我们截取一个有固定特征的样例,比如草地,然后计算该块草地的直方图,然后用这个直方图去和整幅图像的直方图做对比,根据一定的判断条件,就能得出相似的即为草地。

看着就像是语义分割,其实一定意义上这就是语义分割,这不过直方图反向分割的依据是人为计算的(直方图),后者分割的依据是靠在神经网络中学习得来的。

我们先看一下opencv直方图反向计算得API:

void cv::calcBackProject(
  const Mat *  images, //要进行投影的输入图像的地址,注意该API要求输入的是地址
  int          nimages,//输入图像的数目
  const int *  channels,//要进行投影的通道数
  InputArray   hist,//样本得直方图
  OutputArray  backProject,//输出得反向投影,为Mat类型
  const float ** ranges, //输入直方图得特征空间的取值范围
  double         scale = 1,
  bool          uniform = true
)

一:该API得实现原理是什么呢

假设我们现在有一个四行四列得灰度图,它得灰度值如下图:

说这幅图有什么特征呢?直观上看类似于一个边角,但这是直观上,怎么表示出来呢?深度学习是靠神经网络黑箱计算出来得,我们可以用直方图。

那我们就计算这幅灰度图得直方图,如果以组距为1计算直方图并反向投影到原图,得到得为下图:

可以大概表述一下边角得特征:左下角有6个像素值相同得三角形区域,中间斜向下有四个像素值相同得边界线,以此类推。这就是用直方图得到得边角得特征。

那如果以组距为2计算直方图呢?反向投影后为:

可以看到特征描述得更为广泛了,就像深度学习里,提取更高层次得特征,虽然更为普适,但也会忽略掉一些细节特征。

我们就是拿这个反向投影所表达得特征信息,去和整幅图做对比,来得到特征相似得部分,达到分割得效果。

二:利用反向投影进行语义分割

先看一下我们今天要处理得图片:

我们今天要做得就是将这条公路给提取出来。

1,先读取原图以及样本图,并转换为HSV格式。

  //【1】读取图片
  Mat srcImage = imread("风景图.jpg");
  Mat RoiImage = imread("公路2.png"); 
  //【2】转换为HSV图像
  Mat HsvImage, RoiImage_HSV;
  cvtColor(srcImage, HsvImage, COLOR_BGR2HSV);
  cvtColor(RoiImage, RoiImage_HSV, COLOR_BGR2HSV);

为什么转HSV呢?因为HSV表达颜色更为方便区分,我们今天用到得只有前两个通道:H(色调)和S(饱和度),不用V(亮度)。

来看一下我们截取得样本图:

这是我们在公路上随便截取得一块儿样本,可以看到整条公路大概都是这个样子。

2,计算样本图得直方图并进行归一化

  //【3】计算公路的直方图
  MatND roiHist; //直方图对象
  int dims = 2;  //特征数目(直方图维度)
  float hranges[] = { 0,180 }; //特征空间的取值范围
  float Sranges[] = { 0,256 };
  const float *ranges[] = { hranges,Sranges };
  int size[] = { 20,32 };  //存放每个维度的直方图的尺寸的数组
  int channels[] = {0,1};  //通道数
  calcHist(&RoiImage_HSV,1, channels, Mat(), roiHist, dims, size, ranges);
  //【4】直方图归一化
  normalize(roiHist, roiHist, 0, 255, NORM_MINMAX);

代码第7行,我们计算H和S通道直方图的组距分别为20和32,我们采用更小的组距来抓取更大的特征区域。

为什么要归一化呢,直方图反向投影到原图后,原图各位置表示的是整幅图中等于该点像素值的数量,归一化后就变成概率了。

3,将计算的归一化后的直方图进行反向投影

  //【5】反向投影
  Mat proImage; //投影输出图像
  calcBackProject(&HsvImage, 1, channels, roiHist, proImage, ranges);

反向投影后的原图:

可以大概看出公路的轮廓了吧?

4,上一篇图像腌膜Mask的常规操作你真的信手拈来吗?介绍了掩码操作,这里我们就要用掩码将公路给抠出来显示:

  //图像掩码Mask操作
  threshold(proImage, proImage, 50, 255, THRESH_BINARY);//对mask进行二值化,将mask进一步处理
  Mat dstImage = Mat::zeros(srcImage.size(),CV_8UC3);
  srcImage.copyTo(dstImage, proImage);
  imshow("掩码操作", dstImage);

显示结果:

效果并不是想象中那么好是吧哈,感觉还是语义分割要更准确些。但准确能当女朋友吗?

后期再加上些边缘检测和霍夫直线变换,和一些其他骚操作,就可以提取公路啊,车道线啥的了。


如果觉的有帮助,就转发分享一下叭~嗯,,粉丝也该涨涨了。

点个在看,就可以评论啦~

本文分享自微信公众号 - Opencv视觉实践(gh_31e12b1be0e0),作者:是周旋哎

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【opencv】带你再学一遍直方图

    直方图到底可以干什么呢?我觉得最明显的作用就是有利于你对这个图像进行分析了,直方图就像我们常用的统计图,只不过直方图统计的是图片的一些特征,例如像素值(这是最常...

    周旋
  • 【对二寸照片的摧残】一:人脸马赛克

    前两天在CSDN刷到个上首页推荐的利用python进行二寸照片换底色的博文,然后看着我丑不拉几(帅出天际)的二寸平头小照片,我也忍不住了。

    周旋
  • 使用OpenCV进行模糊检测(拉普拉斯算子)

    这只超可爱、超活跃家养小猎犬可能是有史以来拍照次数最多的狗。从8周大我们得到它的时候,到现在,不到3年的时间,我们已经收集了6000多张狗狗的照片。

    周旋
  • 深入理解MySQL8.0直方图

    墨墨导读:MySQL 8.0 新功能直方图,继承于Oracle ,MairaDB的实现方式。本文从MySQL角度解释,直方图是什么。

    数据和云
  • MYSQL 8 Histogram statistics 直方图,开始开挂的MYSQL

    周六日,松懈了,罪过罪过, MYSQL 从8.0开始就开始正式走到开挂数据库得行列,估计8.0铺开后,大部分原先的MYSQL的经验的进行一次洗牌,今天就从MYS...

    AustinDatabases
  • 任意半径中值滤波(扩展至百分比滤波器)O(1)时间复杂度算法的原理、实现及效果。

    主要参考论文:Median Filter in Constant Time.pdf

    用户1138785
  • 【DB笔试面试634】在Oracle中,什么是直方图(Histogram)?直方图的使用场合有哪些?

    在Oracle数据库中,CBO会默认认为目标列的数据在其最小值(LOW_VALUE)和最大值(HIGH_VALUE)之间是均匀分布的,并且会按照这个均匀分布原则...

    小麦苗DBA宝典
  • C++ OpenCV直方图计算

    上述直方图概念是基于图像像素值,其实是对图像梯度,每个像素的角度、等一切图像的属性值,我们都可以建立直方图。这个才是直方图的概念的真正意义,不过是基于图像像素灰...

    Vaccae
  • 机器视觉算法(第13期)----直方图处理中的两大神器!

    上期我们一起揭开了图像处理中的卷积操作的疑惑, 机器视觉算法(第12期)----图像处理中的卷积操作真的是在做卷积吗? 今天,我们一起看下直方图处理中的两大神器...

    智能算法
  • 【从零学习OpenCV 4】直方图匹配

    经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社...

    小白学视觉

扫码关注云+社区

领取腾讯云代金券