直方图反向投影(Back Projection)
反向投影是反映直方图模型在目标图像中的分布情况。
简单点说就是用直方图模型去目标图像中寻找是否有相似的对象。通常用HSV色彩空间的HS两个通道直方图模型。
反向投影 – 步骤
1.建立直方图模型
2.计算待测图像直方图并映射到模型中
3.从模型反向计算生成图像
实现步骤与相关API
加载图片imread
将图像从RGB色彩空间转换到HSV色彩空间cvtColor
计算直方图和归一化calcHist与normalize
Mat与MatND其中Mat表示二维数组,MatND表示三维或者多维数据,此处均可以用Mat表示。
计算反向投影图像 - calcBackProject
void calcHist(
const Mat* images, //输入图像
int nimages, //输入图像的个数
const int* channels, //需要统计直方图的第几通道
InputArray mask, //掩膜,计算掩膜内的直方图 ...Mat()
OutputArray hist, //输出的直方图数组
int dims, //需要统计直方图通道的个数
const int* histSize, //指的是直方图分成多少个区间,就是 bin的个数
const float** ranges, //统计像素值得区间
bool uniform=true, //是否对得到的直方图数组进行归一化处理
bool accumulate=false //在多个图像时,是否累计计算像素值得个数
)
Mat src; Mat hsv; Mat hue;
int bins = 12;
void Hist_And_Backprojection(int, void*);
int main(int argc, char** argv) {
src = imread(STRPAHT3);
if (src.empty()) {
printf("could not load image...\n");
return -1;
}
//转hsv
cvtColor(src, hsv, CV_BGR2HSV);
hue.create(hsv.size(), hsv.depth());
int nchannels[] = { 0, 0 };
//将输入数组的指定通道复制到输出数组的指定通道。
mixChannels(&hsv, 1, &hue, 1, nchannels, 1);
createTrackbar("Histogram Bins:", "window_image", &bins, 180, Hist_And_Backprojection);
Hist_And_Backprojection(0, 0);
imshow("window_image", src);
waitKey(0);
return 0;
}
void Hist_And_Backprojection(int, void*) {
float range[] = { 0, 180 };
const float *histRanges = { range };
Mat h_hist;
//计算图像直方图
calcHist(&hue, 1, 0, Mat(), h_hist, 1, &bins, &histRanges, true, false);
// 归一化
normalize(h_hist, h_hist, 0, 255, NORM_MINMAX, -1, Mat());
Mat backPrjImage;
//计算反向投影图像
calcBackProject(&hue, 1, 0, h_hist, backPrjImage, &histRanges, 1, true);
imshow("BackProj", backPrjImage);
return;
}