026-Opencv筆記-直方圖反向投影

直方圖反向投影(Back Projection)

反向投影是反映直方圖模型在目標圖像中的分布情況
簡單點說就是用直方圖模型去目標圖像中尋找是否有相似的對象。通常用HSV色彩空間的HS兩個通道直方圖模型
反向投影步驟
1.建立直方圖模型
2.計算待測圖像直方圖并映射到模型中
3.從模型反向計算生成圖像

#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace std;
using namespace cv;

Mat src; Mat hsv; Mat hue; 
int bins = 12;
void Hist_And_Backprojection(int, void*);

int main(int argc, char** argv) {
    src = imread("D:/girl.jpg");
    if (src.empty()) {
        printf("could not load image...\n");
        return -1;
    }
    const char*  window_image = "input image";
    namedWindow(window_image, CV_WINDOW_NORMAL);
    namedWindow("BackProj", CV_WINDOW_NORMAL);
    namedWindow("Histogram", CV_WINDOW_NORMAL);

    cvtColor(src, hsv, CV_BGR2HSV);
    hue.create(hsv.size(), hsv.depth());
    int nchannels[] = { 0, 0 };
    //主要就是把輸入的矩陣(或矩陣數(shù)組)的某些通道拆分復制給對應的輸出矩陣(或矩陣數(shù)組)的某些通道中
    //1-輸入矩陣,2-輸入矩陣的個數(shù),3-輸出矩陣,4-輸出矩陣的個數(shù),
    //5-設置輸入矩陣的通道對應輸出矩陣的通道,規(guī)則如下:首先用數(shù)字標記輸入矩陣的各個通道。輸入矩陣個數(shù)可能多于一個并且每個矩陣的通道可能不一樣,
    //第一個輸入矩陣的通道標記范圍為:0 ~src[0].channels() - 1,第二個輸入矩陣的通道標記范圍為:src[0].channels() ~src[0].channels() + src[1].channels() - 1,
    //以此類推;其次輸出矩陣也用同樣的規(guī)則標記,第一個輸出矩陣的通道標記范圍為:0 ~dst[0].channels() - 1,第二個輸入矩陣的通道標記范圍為:dst[0].channels()
    //~dst[0].channels() + dst[1].channels() - 1, 以此類推;最后,數(shù)組fromTo的第一個元素即fromTo[0]應該填入輸入矩陣的某個通道標記,而fromTo的第二個元素即
    //fromTo[1]應該填入輸出矩陣的某個通道標記,這樣函數(shù)就會把輸入矩陣的fromTo[0]通道里面的數(shù)據(jù)復制給輸出矩陣的fromTo[1]通道。fromTo后面的元素也是這個
    //道理,總之就是一個輸入矩陣的通道標記后面必須跟著個輸出矩陣的通道標記。
    //6-即參數(shù)fromTo中的有幾組輸入輸出通道關系,其實就是參數(shù)fromTo的數(shù)組元素個數(shù)除以2.
    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);

    int hist_h = 400;
    int hist_w = 400;
    Mat histImage(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 - cvRound(h_hist.at<float>(i) * (400 / 255)))),
            Point(i*bin_w, hist_h),
            Scalar(0, 0, 255), -1);
    }
    imshow("Histogram", histImage);

    return;
}


?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 直方圖和條形圖的區(qū)別是什么? 以灰度圖像為例子,直方圖有256個條目(或稱為容器)。0號容器給出值為0的像素的個數(shù)...
    Optimization閱讀 4,458評論 0 2
  • 1 、反向投影 反向投影是反映直方圖模型在目標圖像中的分布情況簡單點說就是用直方圖模型去目標圖像中尋找是否有相似的...
    劉玉春_164c閱讀 1,163評論 0 0
  • 本章包括以下內(nèi)容: 計算圖像直方圖; 利用查找表修改圖像外觀; 直方圖均衡化; 反向投影直方圖檢測特定圖像內(nèi)容; ...
    sumpig閱讀 2,776評論 0 1
  • 在日常做CV的過程中,慢慢的就得去琢磨怎么使用一些直觀的方式來展現(xiàn)數(shù)據(jù),甚至來展現(xiàn)一些圖片的區(qū)別。在Python中...
    云時之間閱讀 984評論 0 0
  • OpenCV 之ios 反向投影 目標 本文檔嘗試解答如下問題: 什么是反向投影,它可以實現(xiàn)什么功能? 如何使用O...
    充滿活力的早晨閱讀 651評論 0 2

友情鏈接更多精彩內(nèi)容