直方圖反向投影學習-----個人理解(你究竟是不是凶手)


今天重新學習了一下反向直方圖,個人是這樣理解的:通過計算模型(現場證據)的圖像直方圖,再計算待測試(嫌疑人)的圖像直方圖,然后將嫌疑人的直方圖映射到現場證據的直方圖中,再將結果顯示出來。

 

 原理可以看一下別人的:https://blog.csdn.net/fengye2two/article/details/79113560

 

直方圖歸一化那么對應的直方圖高度就是概率咯,如果你的待測試對象的結果值很大(或者說你的圖像更亮),那么說明你是凶手的嫌疑很大!

不過前提是在手掌局部進行繪制直方圖,如果對整個圖像繪制直方圖,你會發現bin值(橫坐標)很小的地方,其值也可能很大,因為圖上不僅只有手掌部分,還有其他四個角的地方。

 

參考官方文檔:

 

下面附上可直接運行的代碼和測試圖片 1 #include <opencv2/opencv.hpp>

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <Vector>
#include <string>

using namespace std;
using namespace cv;//這句話必須加入,如果不加入,則下面的統一寫成cv::
 
Mat src, hsv, hue, test, test_hue;
const char* window_image = "input image";
int bins = 180;
int main()
{
    src = imread("d:/img/hand.jpg");
    test = imread("d:/img/hand2.jpg");
    namedWindow(window_image, CV_WINDOW_AUTOSIZE);
    namedWindow("test image", CV_WINDOW_AUTOSIZE);
    namedWindow("BackProject", CV_WINDOW_AUTOSIZE);
    namedWindow("Histogram", CV_WINDOW_AUTOSIZE);//histogram 柱狀圖
    imshow(window_image, src);
    imshow("test image", test);

    //將BGR圖像轉化為HSV圖像
    cvtColor(src, hsv, CV_BGR2HSV);
    hue.create(hsv.size(), hsv.depth());
    int nchannels[] = { 0, 0 };
    mixChannels(&hsv, 1, &hue, 1, nchannels, 1);

    //這是待檢測圖像
    cvtColor(test, test, CV_BGR2HSV);
    test_hue.create(test.size(), test.depth());
    //int nchannels[] = { 0, 0 };
    mixChannels(&test, 1, &test_hue, 1, nchannels, 1);

    //計算demo的直方圖
    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());

    //將test的圖像根據h_hist,計算反向直方圖結果
    Mat backProjImage;
    calcBackProject(&test_hue, 1, 0, h_hist, backProjImage, &histRanges, 1, true);
    imshow("BackProject", backProjImage);

    int hist_h = 400;
    int hist_w = 400;
    Mat histImage;
    histImage.create(hist_w, hist_h, CV_8UC3), Scalar(0, 0, 0);
    int bin_w = (hist_w / bins);
    for (int i = 1; i < bins; i++) {
        rectangle(histImage,
            Point((i - 1)*bin_w, (hist_h - cvRound(h_hist.at<float>(i - 1)*(400 / 255)))),
            Point(i*bin_w, hist_h),
            Scalar(0, 0, 255), -1);
    }
    imshow("Histogram", histImage);

    imshow(window_image, src);

    waitKey(0);
    return 0;
}

 

圖片:第一張為demo,第二張為test

結果:

 

以上是個人學習理解,本人也是小白一枚,若大佬們發現有錯誤,請多多還請多多包涵多多指教!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM