0018-图像直方图的反向投影的计算

直方图反向投影的用途这里暂时不讲,先给大家看一个简单的例子,通过这个例子让大家了解到直方图反向投影是怎么样的一种运算,大家了解它的运算后就可以发挥自己的才智去运用它了。

设有原灰度图像矩阵:

Image=
  9    5    7    9
  1    2    3    5
  6    7    8    1
  2    3    5    6

将灰度值划分为如下四个区间:

[0,2]   [3,5]   [6,7]   [8,10]

很容易得到这个图像矩阵的直方图hist= 4  5  4  3

好,接下来计算反向投影矩阵:

反向投影矩阵的大小和原灰度图像矩阵的大小相同!

原图像中坐标为(0,0)的灰度值为9,9位于区间[8,10] 中,区间[8,10] 对应的直方图值为3,所以反向投影矩阵中中坐标为(0,0)的值记为3

按上面的计算方法,可以得到Image的直方图反向投影矩阵为:

back_Projection=
  3    5    4    3
  4    4    5    5
  4    4    3    4
  4    5    5    4
从上面的计算过程我们来理解直方图的反向投影到底代表什么

各位朋友,如果你想知道“直方图的反向投影到底代表什么”,可以搜索公众号"qxsf321",并关注,然后回复0018获取答案。

OpenCV提供了函数calcBackProject来计算图像的直方图反向投影,函数原型如下
C++: void calcBackProject(const Mat* images, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges, double scale=1, bool uniform=true )
参数介绍下
images:源图像数组指针
nimages:源图像张数
channels:要计算直方图反向投影的通道编号。通道编号方法:第一张图的通道编号为0至images[0].channels()-1,第二张图的通道编号为images[0].channels()至images[0].channels() + images[1].channels()-1,以此类推,注意这个参数是指针。
hist:图像的直方图矩阵
backProject:函数计算出的直方图反向投影图的存储矩阵
ranges:各个通道取值的边界值或区间划分。
scale:反向投影图的尺度系数。最终函数生成的的反向投影图会乘以这个系数。
uniform:直方图是否均匀化的标志,意义暂时不清楚,等以后搞清楚了再来补充说明。

用函数calcBackProject来计算图像的直方图反向投影的源代码如下
源码中使用的图像下载链接:http://pan.baidu.com/s/1kUJMx1t 密码:r3d3

//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>

#include <iostream>

using namespace cv;
using namespace std;

int main()
{

        Mat img = imread("02.jpg");
        if (img.empty())
        {
                cout << "Error: Could not load image" << endl;
                return 0;
        }

        Mat srcImage;
        cvtColor(img, srcImage, CV_BGR2GRAY);

        imshow("【原图的灰度图】", srcImage);

        //为计算直方图配置变量  
        //首先是需要计算的通道编号,就是需要计算哪个通道的直方图(BGR空间需要确定计算,计算方法见帖子中对相关参数的说明)  
        int channels = 0;
        //然后是定义直方图计算结果的存储空间
        Mat dstHist;
        //接下来是直方图的每一个维度的数目(这个数目用于将每一维度的数值分组)  
        int histSize[] = { 256 };
        //最后是确定每个维度的取值范围,就是每一维度的横坐标的取值范围  
        //首先得定义一个数组用来存储单个维度的的取值范围  
        float midRanges[] = { 0, 256 };
        //然后把这个数组再放到一个二维数组中
        const float *ranges[] = { midRanges };

        const float *ranges2 = { midRanges };

        //准备工作做好后,就可以调用calcHis函数计算直方图数据了
        calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false);

        //calcHist函数调用结束后,dstHist变量中将储存直方图数据 

        //对直方图数据进行归一化处理,把值归一化到0到255
        normalize(dstHist, dstHist, 0, 255, NORM_MINMAX, -1, Mat());

        // 计算反向投影
        Mat backproj;
        calcBackProject(&srcImage, 1, 0, dstHist, backproj, &ranges2, 1, true);

        /// Draw the backproj  
        imshow("BackProj", backproj);

        waitKey(0);

        return 0;
}


代码说明
计算直方图的代码这里就不说了,不清楚的可参看博文https://blog.csdn.net/lehuoziyuan/article/details/84064822
这里说下归一化函数normalize,原型如下
C++: void normalize(InputArray src, InputOutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )
参数意义如下
src:待归一化的矩阵
dst:归一化后的矩阵
alpha:归一化后值的下边界
beta: 归一化后值的上边界,这个值当normType=NORM_L1或normType=NORM_L2时无效。
normType:归一化类型,具体类型如下有NORM_INF, NORM_L1, or NORM_L2,实际上是选择哪个数成为归一化后的最大值。当为NORM_INF时,最大值为beta;当为NORM_L1时,最大值为矩阵的L1范数;当为NORM_L2时,最大值为矩阵的L2范数;
dtype:当这个值为负值时,输出矩阵和输入矩阵的数据类型一致;当为其它值时,不仅数据类型要一致,深度和通道数也要一样。
mask:掩码阵列。掩码中的非0元素对应的图像元素将会被计算,0元素则被屏蔽不参与计算,可选参数。
程度运行结果截图如下


 

猜你喜欢

转载自blog.csdn.net/lehuoziyuan/article/details/84066265