这篇博客我们学习直方图反向投影。
反向投影是一种记录给定图像中的像素点如何适应直方图模型像素分布的方式,简单来讲,反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的特征。反向投影在某一位置的值就是原图对应位置像素值在原图像中的总数目。
反向投影是将特征“反映”到图像上,对于物体特征识别和分割有着很大的作用。
进行反向投影的一般步骤:
1、获取直方图的源,比如我们要对手进行反向投影,那么直方图的源就是肤色的ROI
2、获取需要反向投影的图像
3、计算直方图,通常是在HSV模型中计算,毕竟反向投影的一大工作就是区分颜色
4、反向投影
5、显示
void cv::calcBackProject ( const Mat * images,
int nimages,
const int * channels,
InputArray hist,
OutputArray backProject,
const float ** ranges,
double scale = 1,
bool uniform = true
)
参数解释:
const Mat* images:输入图像,图像深度必须位CV_8U,CV_16U或CV_32F中的一种,尺寸相同,每一幅图像都可以有任意的通道数
int nimages:输入图像的数量
const int* channels:用于计算反向投影的通道列表,通道数必须与直方图维度相匹配,第一个数组的通道是从0到image[0].channels()-1,第二个数组通道从图像image[0].channels()到image[0].channels()+image[1].channels()-1计数
InputArray hist:输入的直方图,直方图的bin可以是密集(dense)或稀疏(sparse)
OutputArray backProject:目标反向投影输出图像,是一个单通道图像,与原图像有相同的尺寸和深度
const float ranges**:直方图中每个维度bin的取值范围
double scale=1:可选输出反向投影的比例因子
bool uniform=true:直方图是否均匀分布(uniform)的标识符,有默认值true
另外两种定义形式如下:
void cv::calcBackProject ( const Mat * images,
int nimages,
const int * channels,
const SparseMat & hist,
OutputArray backProject,
const float ** ranges,
double scale = 1,
bool uniform = true
)
void cv::calcBackProject ( InputArrayOfArrays images,
const std::vector< int > & channels,
InputArray hist,
OutputArray dst,
const std::vector< float > & ranges,
double scale
)
#include
#include
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("C:\\Users\\Dell\\Desktop\\picture\\opencv_tutorial\\opencv_tutorial\\data\\images\\target.png");
Mat model = imread("C:\\Users\\Dell\\Desktop\\picture\\opencv_tutorial\\opencv_tutorial\\data\\images\\sample.png");
if (src.empty() || model.empty()) {
printf("could not load image...\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 和Mat都行,下面这里
MatND backproj;
calcBackProject(&image_hsv, 1, channels, roiHist, backproj, ranges, 1.0);
imshow("BackProj", backproj);
}