【OpenCV图像处理】1.26 直方图反向投影(Back Projection)

1. 相关理论

  • 反向投影

    • 反向投影是反映直方图模型在目标图像中的分布情况
    • 简单点说就是用直方图模型去目标图像中寻找是否有相似的对象。通常用HSV色彩空间的HS两个通道直方图模型
  • 反向投影 步骤

    • 1.建立直方图模型
    • 2.计算待测图像直方图并映射到模型中
    • 3.从模型反向计算生成图像
  • 实现步骤与相关API

    • 加载图片imread

    • 将图像从RGB色彩空间转换到HSV色彩空间cvtColor

    • 计算直方图和归一化calcHist与normalize

    • Mat与MatND其中Mat表示二维数组,MatND表示三维或者多维数据,此处均可以用Mat表示。

    • 计算反向投影图像 - calcBackProject ,一共三个calcBackProject函数,参数不同,利用的是函数重载功能,这里只介绍第一个重载函数

      void cv::calcBackProject(	
      	const Mat * images,
      	int nimages,
      	const int * channels,
      	InputArray hist,
      	OutputArray backProject,
      	const float ** ranges,
      	double scale = 1,
      	bool uniform = true 
      )	
      

    以上参数的详细解释:

    • images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same size. Each of them can have an arbitrary number of channels.
    • nimages Number of source images.
    • channels The list of channels used to compute the back projection. The number of channels must match the histogram dimensionality. The first array channels are numerated from 0 to images[0].channels()-1 , the second array channels are counted from images[0].channels() to images[0].channels() + images[1].channels()-1, and so on.
    • hist Input histogram that can be dense or sparse.
    • backProject Destination back projection array that is a single-channel array of the same size and depth as images[0] .
    • ranges Array of arrays of the histogram bin boundaries in each dimension. See calcHist .
    • scale Optional scale factor for the output back projection.
    • uniform Flag indicating whether the histogram is uniform or not (see above).

2. 源码 & 效果展示

源码:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>

using namespace std;
using namespace cv;

#ifndef P26
#define P26 26
#endif

#if P27 //直方图反向投影
Mat src; Mat hsv; Mat hue;
int bins = 12;
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),
                  Scalar(0, 0, 255), -1);
    }
    imshow("Histogram", histImage);

    return;
}
#endif

int main() {
    std::string path = "../color_line.JPG";
    cv::Mat img = cv::imread(path, 5);
    if(img.empty())
    {
        std::cout << "open file failed" << std::endl;
        return -1;
    }
    
#if P26 //直方图反向投影
	src = img;
    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:", str_input, &bins, 180, Hist_And_Backprojection);
    Hist_And_Backprojection(0, 0);

    imshow(str_input, src);
#endif

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

效果展示:
在这里插入图片描述

发布了134 篇原创文章 · 获赞 30 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/donaldsy/article/details/102746139