反向投影图

反向投影图  

2010-12-28 22:25:51|  分类: OpenCV学习|字号 订阅

        图像的反向投影图是用输入图像的某一位置上像素值(多维或灰度)对应在直方图的一个bin上的值来代替该像素值,所以得到的反向投影图是单通的。用统计学术语,输出图像象素点的值是观测数组在某个分布(直方图)下的概率。
反向投影图 - 十三月de天空 - 十三月de天空
 
其中 b(xi) 表示在位置 xi 上像素对应的直方图第 b(xi) bin ,直方图共 m bin ,qu表示第ubin的值。

还是以例子说明
(1)例如灰度图像如下

Image=

  0    1    2    3

  4    5    6    7

  8    9   10   11

  8    9   14   15

(2)该灰度图的直方图为(bin指定的区间为[0,3)[4,7)[8,11)[12,16)

Histogram=

  4    4    6    2

(3)反向投影图

Back_Projection=

  4    4    4    4

  4    4    4    4

  6    6    6    6

  6    6    2    2

例如位置(0,0)上的像素值为0,对应的bin[0,3),所以反向直方图在该位置上的值这个bin的值4


测试代码如下:

#include 

using namespace std;

#include 

#include 

#include 

 

int main()

{

         uchar data[]={0,1,2,3,4,5,6,7,8,9,10,11,8,9,14,15};     //图像数据

         CvMat mat=cvMat(4,4,CV_8UC1,data);

 

         IplImage g_img;      //灰度图

         cvGetImage(&mat,&g_img);

 

         //打印图像数据

         cout<<"Image="<

         for(int i=0;i

         {

                   uchar* ptr=(uchar*)(g_img.imageData+i*g_img.widthStep);

                   for(int j=0;j

                   {

                            cout<"  ";

                   }

                   cout<

         }

 

         //计算图像直方图

         IplImage* imgs[]={&g_img};

         int g_bin=4;

         int size[]={g_bin};

         float g_ranges[]={0,4,8,12,16};

         float* ranges[]={g_ranges};

         CvHistogram* hist=cvCreateHist(1,size,CV_HIST_ARRAY,ranges,0);

         cvCalcHist(imgs,hist);

 

         //打印图像直方图数据

         cout<<"Histogram="<

         for(int i=0;i

         {

                   cout<"  ";

         }

         cout<

 

         //计算反向投影图

         IplImage* back_project=cvCreateImage(cvGetSize(&g_img),g_img.depth,1);

         cvCalcBackProject(imgs,back_project,hist);

 

         //打印反向投影图数据

         cout<<"Back_Projection="<

         for(int i=0;iheight;i++)

         {

                   uchar* ptr=(uchar*)(back_project->imageData+i*back_project->widthStep);

                   for(int j=0;jwidth;j++)

                   {

                            cout<"  ";

                   }

                   cout<

         }

 

}


直方图的方向投影(转)

作者:飞夺泸定桥 | 出处:博客园 | 阅读77次 2011/6/7 11:47:51
1.反向投影的作用是什么?
    反向投影用于在 输入图像(通常较大)中查找特定图像(通常较小或者仅1个像素,以下将其称为 模板图像)最匹配的点或者区域,也就是 定位模板图像出现在输入图像的位置。
2.反向投影如何查找(工作)?
    查找的方式就是不断的在输入图像中切割跟模板图像大小一致的图像块,并用直方图对比的方式与模板图像进行比较。

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
(1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
(2)生成临时图像的直方图;
(3)用临时图像的直方图和模板图像的直方图对比,对比结果记为c;
(4)直方图对比结果c,就是结果图像(0,0)处的像素值;
(5)切割输入图像从(0,1)至(10,11)的临时图像,对比直方图,并记录到结果图像;
(6)重复(1)~(5)步直到输入图像的右下角。

 

(本图片引用自http://www.opencv.org.cn)
3.反向投影的结果是什么?
    反向投影的结果包含了:以每个输入图像像素点为起点的直方图对比结果。可以把它看成是一个二维的浮点型数组,二维矩阵,或者单通道的浮点型图像。
4.特殊情况怎么样?
    如果输入图像和模板图像一样大,那么反向投影相当于直方图对比。如果输入图像比模板图像还小,直接罢工~~。


opencv 反向投影

分类: OPENCV   438人阅读  评论(2)  收藏  举报
image 测试 float 语言

原理:反向投影是一种记录给定图像中的像素点如何适应直方图模型像素分布的方式。

所谓反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征。

假设你已经通过下图得到一个肤色直方图(Hue-Saturation), 旁边的直方图就是 模型直方图 ( 代表手掌的皮肤色调).你可以通过掩码操作来抓取手掌所在区域的直方图:

我们要做的就是使用 模型直方图 (代表手掌的皮肤色调) 来检测测试图像中的皮肤区域。以下是检测的步骤

  1. 对测试图像中的每个像素 ( p(i,j) ),获取色调数据并找到该色调(( h_{i,j}, s_{i,j} ) )在直方图中的bin的位置。

  2. 查询 模型直方图 中对应的bin - ( h_{i,j}, s_{i,j} ) - 并读取该bin的数值。

  3. 将此数值储存在新的图像中(BackProjection)。 你也可以先归一化 模型直方图 ,这样测试图像的输出就可以在屏幕显示了。

  4. 通过对测试图像中的每个像素采用以上步骤, 我们得到了下面的 BackProjection 结果图:

使用统计学的语言,  BackProjection 中储存的数值代表了测试图像中该像素属于皮肤区域的 概率 。比如以上图为例, 亮起的区域是皮肤区域的概率更大(事实确实如此),而更暗的区域则表示更低的概率(注意手掌内部和边缘的阴影影响了检测的精度)。

 

上代码:

[cpp]  view plain copy
  1. /// 全局变量  
  2. Mat src; Mat hsv; Mat hue;  
  3. int bins = 25;  
  4.   
  5. /// 函数申明  
  6. void Hist_and_Backproj(intvoid* );  
  7.   
  8. /** @函数 main */  
  9. int main(  )  
  10. {  
  11.   /// 读取图像  
  12.   src = imread( "e:\\kankan\\1.jpg" );  
  13.   /// 转换到 HSV 空间  
  14.   cvtColor( src, hsv, CV_BGR2HSV );  
  15.   
  16.   /// 分离 Hue 通道  
  17.   hue.create( hsv.size(), hsv.depth() );  
  18.   int ch[] = { 0, 0 };  
  19.   mixChannels( &hsv, 1, &hue, 1, ch, 1 );  
  20.   
  21.   /// 创建 Trackbar 来输入bin的数目  
  22.   char* window_image = "Source image";  
  23.   namedWindow( window_image, CV_WINDOW_AUTOSIZE );  
  24.   createTrackbar("* Hue  bins: ", window_image, &bins, 180, Hist_and_Backproj );  
  25.   Hist_and_Backproj(0, 0);  
  26.   
  27.   /// 现实图像  
  28.   imshow( window_image, src );  
  29.   
  30.   /// 等待用户反应  
  31.   waitKey(0);  
  32.   return 0;  
  33. }  
  34.   
  35.   
  36. /** 
  37.  * @函数 Hist_and_Backproj 
  38.  * @简介:Trackbar事件的回调函数 
  39.  */  
  40. void Hist_and_Backproj(intvoid* )  
  41. {  
  42.   MatND hist;  
  43.   int histSize = MAX( bins, 2 );  
  44.   float hue_range[] = { 0, 180 };  
  45.   const float* ranges = { hue_range };  
  46.   
  47.   /// 计算直方图并归一化  
  48.   calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, truefalse );  
  49.   normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() );  
  50.   
  51.   /// 计算反向投影  
  52.   MatND backproj;  
  53.   calcBackProject( &hue, 1, 0, hist, backproj, &ranges, 1, true );  
  54.   
  55.   /// 显示反向投影  
  56.   imshow( "BackProj", backproj );  
  57.   
  58.   /// 显示直方图  
  59.   int w = 400; int h = 400;  
  60.   int bin_w = cvRound( (double) w / histSize );  
  61.   Mat histImg = Mat::zeros( w, h, CV_8UC3 );  
  62.   
  63.   forint i = 0; i < bins; i ++ )  
  64.      { rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( hist.at<float>(i)*h/255.0 ) ), Scalar( 0, 0, 255 ), -1 ); }  
  65.   
  66.   imshow( "Histogram", histImg );  
  67. }  

                                                                                                                    直方图  
效果图:                    原图                                                                                                                                                                             

 


 图上的不好,请见谅!!!

 



你可能感兴趣的:(openCV,image)