反向投影的工作原理
反向投影圖中,某一位置(x,y)的像素值 = 原圖對應位置(x,y)像素值在原圖的總數目。 即若原圖中(5,5)位置上像素值為 200,而原圖中像素值為 200 的像素點有 500 個,則反向投影圖中(5,5)位置上的像素值就設為 500。
具體步驟:
- 計算圖像直方圖:統計各像素值(或像素區間)在原圖的總數量。
- 將直方圖數值歸一化到 [0,255] 。
- 對照直方圖,實現反向投影。
反向投影的作用
反向投影用於在輸入圖像(通常較大)中查找與模板圖像(通常較小甚至僅 1 個像素)最匹配的點或區域,也就是確定模板圖像在輸入圖像中的位置。
計算反向投影:calcBackProject 函數
void calcBackProject(const Mat* images, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges, double scale = 1, bool uniform = true);
- images,輸入的圖像(或圖像集),它們需為相同深度(CV_8U 或 CV_32F)和相同尺寸,而通道數任意。
- nimages,輸入圖像個數。
- channels,需要統計圖像的通道索引即第幾個通道,第一幅圖的通道索引可選范圍 [0, images[0].channels() - 1],第二幅圖的通道索引可選范圍 [images[0].channels(), images[0].channels() + images[1].channels() - 1] 以此類推。
- hist,輸入的直方圖。
- backProject,反向投影圖像,需為單通道,並且和 images[0] 有相同的大小和深度。
- ranges,直方圖中 x 軸的取值范圍。
- scale,縮放因子,backProject [i][j] = scale * hist [images[k] [i][j]],有默認值 1。
- uniform,直方圖是否均勻化的標識符,有默認值 true。
代碼示例:
#include<opencv.hpp> #include<iostream>
using namespace std; using namespace cv; Mat src, hsvImg, hist; vector<Mat>hsv; int histSize = 5; void ChangeHistSize(int, void*) { if (histSize == 0) { histSize = 1; } //計算 H 通道直方圖 https://www.cnblogs.com/bjxqmy/p/12378312.html
int channels[] = { 0 }; float hr[] = { 0,180 }; const float *ranges[] = { hr }; calcHist(&hsv[0], 1, &channels[0], Mat(), hist, 1, &histSize, &ranges[0]); normalize(hist, hist, 255, 0, NORM_L1); imshow("hist", hist); //計算反向投影
Mat backImg; calcBackProject(&src, 1, &channels[0], hist, backImg, &ranges[0], 1); imshow("backImg", backImg); } int main() { src = imread("C:/Users/齊明洋/Desktop/證件照/1.jpg"); imshow("src", src); //轉換為 HSV 通道圖像
cvtColor(src, hsvImg, COLOR_BGR2HSV); imshow("hsvImg", hsvImg); //通道分離
split(hsvImg, hsv); imshow("hImg", hsv[0]); namedWindow("backImg"); createTrackbar("histSize", "backImg", &histSize, 180, ChangeHistSize); ChangeHistSize(0, 0); waitKey(0); }
效果演示:


借鑒博客:https://blog.csdn.net/fengye2two/article/details/79113560
