OpenCV中反向投影

OpenCV中反向投影

首先要说的可能要说的就是反向投影,用一个看到的例子来说可能更直观一些。
[ 1 2 3 4 5 6 7 8 9 10 11 12 9 10 13 15 ] \begin{bmatrix}1&2&3&4 \\ 5&6&7&8 \\ 9&10&11&12 \\ 9&10&13&15 \end{bmatrix} 1599261010371113481215
假设该矩阵为一个图像的像素分布,首先我们根据该矩阵找到图像的直方图,假设图像的bin值范围为 [ 1 , 4 ] , [ 5 , 8 ] , [ 9 , 11 ] , [ 12 , 15 ] [1,4],[5,8],[9,11],[12,15] [1,4],[5,8],[9,11],[12,15]
可以得到图像的各个像素的个数:
[ 1 , 4 ] : 4 [1,4]:4 [1,4]:4

[ 5 , 8 ] : 4 [5,8]:4 [5,8]:4

[ 9 , 11 ] : 5 [9,11]:5 [9,11]:5

[ 12 , 15 ] : 3 [12,15]:3 [12,15]:3

我们得到了各个像素的在图像中出现的次数,然后遍历原图像,例如第一个像素点,像素值为1在 [ 1 , 4 ] [1,4] [1,4]这个范围内,所以将该点的像素值改为该范围统计的频值即是4,对所有的像素执行上述的操作,可以得到如下矩阵:
[ 4 4 4 4 4 4 4 4 5 5 5 3 5 5 3 3 ] \begin{bmatrix}4&4&4&4\\4&4&4&4 \\5&5&5&3\\5&5&3&3 \end{bmatrix} 4455445544534433
这个过程就是我们所说的反向投影。

第二个需要知道的是HSV图像。HSV表示一个色彩空间,也是三通道的,类似与RGB图像,在RGB图像中每个通道代表的是三原色之一,而在HSV中每个通道代表的意思与RGB完全不同。
H通道表示色调在OpenCV中取值范围为0-180,
S为饱和度,取值范围为0-255表示颜色接近光谱的程度,一种颜色可以看成时光谱色与白色混合的结果。其中光谱色占的比例越大,颜色的饱和度也就越高。
V为亮度,取值范围为0-255。

HSV通道的获取,利用mixChannels函数来实现:

    hue.create(hsv.size(),hsv.depth());
    int ch[] = {0,0};
    mixChannels(&hsv,1,&hue,1,ch,1);

hsv.depth();在OpenCV中该函数用来显示图像的深度,什么叫图像的深度呢?作为小白的我去求助了度娘,例如灰度图,每个像素的值的范围为0-255,需要8位二进制数才能表示255,所以叫该图的位深为8。

mixChannels(
	输入图像,
	矩阵的数量,
	输出图像,深度和大小必须和输入图像0通道相同
	矩阵的数量,
	被复制通道和要复制到的位置组成索引对,例如从原图的0通道到0通道
	索引对的数目。
);

分离通道时需要注意,HSV中,H在0通道,S在1通道,V在2通道。
在 这 个 地 方 , 有 一 个 疑 惑 , 之 前 我 们 对 图 像 通 道 分 离 都 是 采 用 s p l i t 这 个 函 数 来 进 行 , \color{#f00}在这个地方,有一个疑惑,之前我们对图像通道分离都是采用split这个函数来进行, split 这 里 没 有 使 用 , 那 么 s p l i t 是 否 可 以 呢 所 以 我 就 试 了 一 下 , 发 现 可 以 。 \color{#f00}这里没有使用,那么split是否可以呢所以我就试了一下,发现可以。 使split

 	vector<Mat> v;
    split(hsv,v);
    hue = v[0];

下面就是由OpenCV提供的反向投影的API函数:

calcBackProjection(
	输入图像,深度必须为cv_8u、cv_16u、cv_32f的一种
	输入图像的数量,
	用于反向投影的通道列表
	输入的直方图,
	输出的单通道反向投影的图像,
	直方图中每个维度bin的取值范围
	double scale=1:可选输出反向投影的比例因子
	直方图是否均匀分布的标识符,默认为true
);

下面看一个手敲的小demo:

#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

Mat src,hsv,hue;
int bins = 25;


void Hist_and_Backproj(int,void*)
{
    Mat hist;
    int histSize = MAX(bins,2);
    float hue_range[] = {0,180};
    const float* ranges = {hue_range};

    calcHist(&hue,1,0,Mat(),hist,1,&histSize,&ranges,true,false);
    normalize(hist,hist,0,255,NORM_MINMAX,-1,Mat());
    Mat backproj;
    calcBackProject(&hue,1,0,hist,backproj,&ranges,1,true);

    imshow("backproj",backproj);
}


int main(int argc, char *argv[])
{
    
    src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/map.png");
    cvtColor(src,hsv,CV_BGR2HSV);
    
    hue.create(hsv.size(),hsv.depth());
    int ch[] = {0,0};
    mixChannels(&hsv,1,&hue,1,ch,1);
    //vector<Mat> v;

    //split(hsv,v);
    //hue = v[0];

    namedWindow("Test",CV_WINDOW_AUTOSIZE);
    createTrackbar("Test","Test",&bins,180,Hist_and_Backproj);
    Hist_and_Backproj(0,0);
    waitKey(0);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值