您的位置:首页 > 其它

反向投影(BackProjection)

2015-07-01 21:01 267 查看
所谓反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找测试图像中存在的该特征。

利用Hue直方图解释反向投影原理:

1、获取测试图像中每个像素的hue数据 hi,j,并找到 hi,j 在hue直方图中的bin的位置。

2、查询hue直方图中对应bin的数值。

3、将该数值存储在新的图像中(BackProjection),也可以先归一化hue直方图数值到0-255范围,这样可以直接显示BackProjection图像(单通道图像)。

4、通过对测试图像每个像素采取以上步骤,可以得到最终的BackProjection图像。



代码如下:

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.cpp

#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)图像:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: