若是一幅圖像的區域中顯示的是一種結構紋理或者一個獨特的物體,那麼這個區域的直方圖能夠看做一個機率函數,他給的是某個像素屬於該紋理或物體的機率。ios
所謂反向投影就是首先計算某一特徵的直方圖模型,而後使用模型去尋找測試圖像中存在的該特徵。函數
利用Hue直方圖解釋反向投影原理:測試
一、獲取測試圖像中每一個像素的hue數據 hi,j,並找到 hi,j 在hue直方圖中的bin的位置。ui
二、查詢hue直方圖中對應bin的數值。spa
三、將該數值存儲在新的圖像中(BackProjection),也能夠先歸一化hue直方圖數值到0-255範圍,這樣能夠直接顯示BackProjection圖像(單通道圖像)。code
四、經過對測試圖像每一個像素採起以上步驟,能夠獲得最終的BackProjection圖像。orm
代碼以下:blog
backprojection.h回調函數
#ifndef BACKPROJECTION_H #define BACKPROJECTION_H #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> //全局函數///////////////////////////////// void hist_and_backprojection(int, void* ); #endif // BACKPROJECTION_H
backprojection.cppit
#include "backprojection.h" extern cv::Mat src, hsv, hue; extern int bins; void hist_and_backprojection(int, void* ) { cv::MatND hist; //直方圖bin的數目大小 int histSize = cv::max(bins, 2); float hue_range[] = {0, 180}; const float *ranges = { hue_range }; //計算直方圖並歸一化 cv::calcHist(&hue, 1, //圖像數量 0, //通道數 cv::Mat(), //不使用掩膜 hist, 1, //直方圖維度 &histSize, //每一維直方圖bin的數目 &ranges, //每一維直方圖的範圍 true, false ); //將直方圖bin的數值歸一化到0-255,可方便直接顯示反向投影圖 cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX, -1, cv::Mat()); //計算反向投影 cv::MatND backproj; cv::calcBackProject(&hue, 1, //源圖像的數目 0, //用於計算反向投影值的通道列表 hist, //輸入直方圖 backproj, //單通道反向投影圖像 &ranges, //每一維直方圖bin的範圍 1, true); //顯示反向投影圖 cv::namedWindow("BackProjection"); cv::imshow("BackProjection", backproj); //顯示直方圖 int w = 400, h = 400; int bin_w = cvRound((double)w / histSize); cv::Mat histImg = cv::Mat::zeros( w, h, CV_8UC3 ); for(int i = 0; i < bins; i++) { cv::rectangle(histImg, cv::Point(i*bin_w, h), cv::Point((i+1)*bin_w, h - cvRound(hist.at<float>(i) * h / 255.0) ), cv::Scalar(0, 0, 255), -1); } cv::namedWindow("Histogram"); cv::imshow("Histogram", histImg); }
main.cpp
#include <QtCore/QCoreApplication> #include "backprojection.h" //全局變量///////////////////////////////// cv::Mat src, hsv, hue; int bins = 25; int main(int argc, char *argv[]) { // QCoreApplication a(argc, argv); // return a.exec(); src = cv::imread("../image/HandIndoorColor.jpg", 1); //轉換到HSV cv::cvtColor(src, hsv, cv::COLOR_RGB2HSV); cv::namedWindow("hsvImg"); cv::imshow("hsvImg", hsv); //分離Hue通道(即色相通道) hue.create(hsv.size(), hsv.depth()); int ch[] = {0, 0}; cv::mixChannels(&hsv, 1, &hue, 1, ch, 1); //建立Trackbar來輸入bin的數目 const char *window_image = "Source image"; cv::namedWindow(window_image, cv::WINDOW_AUTOSIZE); cv::createTrackbar("* Hue bins: ",window_image, &bins, 180, hist_and_backprojection //回調函數 ); hist_and_backprojection(0, 0); cv::imshow(window_image, src); //等待用戶反應 cv::waitKey(0); return 0; }
運行結果圖:
滑動條用於調節直方圖bin的數目。
HSV顏色空間圖像:
調節不一樣bin的數目對應的Hue直方圖:
調節不一樣bin的數目對應的反向投影(BackProjection)圖像: