【OpenCV 4】图像的直方图反向投影

一、编程环境:

OpenCV  4.1.0
IDE Visual Studio 2017 Enterprise (15.9.13)
操作系统 Windows 10 x64 中文专业版 (1903)

二、图像的直方图反向投影:

  • 反向投影

反向投影是一种记录给定图像中的像素点如何适应直方图模型像素分布的方式。简单的讲,就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征。例如,你有一个肤色直方图(Hue-Saturation直方图),你可以用它来寻找图像中的肤色区域。

图像的反向投影图是用输入图像的某一位置上像素值(多维或灰度)对应在直方图的一个bin上的值来代替该像素值,所以得到的反向投影图是单通的。

通过反向投影,原始的图像被简化了,而这个简化的过程实际上就是提取出图像的某个特征。所以我们就可以用这个特征来对比两幅图,如果两幅图的反向投影矩阵相似或相同,那么我们就可以判定这两幅图这个特征是相同的。

三、OpenCV 中图像的直方图反向投影计算函数:calcBackProject()

  • 共有三种调用方式(后两种为重载):
void calcBackProject( const Mat* images, int nimages,
                      const int* channels, InputArray hist,
                      OutputArray backProject, const float** ranges,
                      double scale = 1, bool uniform = true );

/* overload */
void calcBackProject( const Mat* images, int nimages,
                      const int* channels, const SparseMat& hist,
                      OutputArray backProject, const float** ranges,
                      double scale = 1, bool uniform = true );

/* overload */
void calcBackProject( InputArrayOfArrays images, const std::vector<int>& channels,
                      InputArray hist, OutputArray dst,
                      const std::vector<float>& ranges,
                      double scale );

四、示例程序:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

const int bins = 256;
Mat src;
const char* winTitle = "input image";
void backProjection_demo(Mat &image, Mat &model);

int main(int argc, char** argv) {
	Mat src = imread("../images/fp_my01.png");
	Mat model = imread("../images/fp_model04.jpg");
	if (src.empty() || model.empty()) {
		printf("不能加载图像!\n");
		return 0;
	}
	namedWindow(winTitle, WINDOW_AUTOSIZE);
	imshow(winTitle, src);
	imshow("model", model);

	backProjection_demo(src, model);


	waitKey(0);
	return 0;
}

void backProjection_demo(Mat &image, Mat &model) {
	Mat model_hsv, image_hsv;
	cvtColor(model, model_hsv, COLOR_BGR2HSV);
	cvtColor(image, image_hsv, COLOR_BGR2HSV);

	// 定义直方图参数与属性
	int h_bins = 32; int s_bins = 32;
	int histSize[] = { h_bins, s_bins };
	// hue varies from 0 to 179, saturation from 0 to 255
	float h_ranges[] = { 0, 180 };
	float s_ranges[] = { 0, 256 };
	const float* ranges[] = { h_ranges, s_ranges };
	int channels[] = { 0, 1 };
	Mat roiHist;
	
	calcHist(&model_hsv, 1, channels, Mat(), roiHist, 2, histSize, ranges, true, false);
	normalize(roiHist, roiHist, 0, 255, NORM_MINMAX, -1, Mat());

	//计算反向投影
	MatND backproj;
	calcBackProject(&image_hsv, 1, channels, roiHist, backproj, ranges, 1.0);
	
	imshow("BackProj", backproj);
}

五、运行效果:

猜你喜欢

转载自blog.csdn.net/kingkee/article/details/93485603