zoukankan      html  css  js  c++  java
  • 【练习7.2】直方图归一化cvNormalizeHist、匹配cvCompareHist及各种匹配方法

    提纲
    题目要求
    程序代码
    结果图片
    要言妙道

      

    题目要求:

     使用三种光照条件下的手的图像,利用cvCalcHist来获得直方图

    a、获得图像HSV三维直方图

    b、匹配三种光照条件下的直方图,使用所有的匹配方法,测试bin的值为2, 8, 16, 32, 256的情况

    程序代码:

     1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
     2 //
     3 //D:\Work\Work_Programming\Source\Image\lena.jpg
     4 
     5 #include "stdafx.h"
     6 #include <cv.h>
     7 #include <highgui.h>
     8 #include <iostream>
     9 
    10 #include <opencv2/legacy/legacy.hpp>
    11 //#pragma comment(lib, "opencv_legacy2411.lib")
    12 
    13 using namespace cv;
    14 using namespace std;
    15 
    16 //函数声明-->--->-->--->-->--->-->--->//
    17 
    18 
    19 //<--<--<--<--<--<--<--<--<--函数声明//
    20 
    21 int _tmain(int argc, _TCHAR* argv[])
    22 {
    23     char * soutceFile = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\hand_sample3.jpg";
    24     IplImage * image_Source = cvLoadImage(soutceFile, CV_LOAD_IMAGE_UNCHANGED);
    25     assert(image_Source);
    26 
    27     IplImage *image_HSV = cvCreateImage(cvGetSize(image_Source), IPL_DEPTH_8U, 3);
    28     cvCvtColor(image_Source, image_HSV, CV_BGR2HSV);
    29     IplImage * image_h = cvCreateImage(cvGetSize(image_HSV), IPL_DEPTH_8U, 1);
    30     IplImage * image_s = cvCreateImage(cvGetSize(image_HSV), IPL_DEPTH_8U, 1);
    31     IplImage * image_v = cvCreateImage(cvGetSize(image_HSV), IPL_DEPTH_8U, 1);
    32     cvCvtPixToPlane(image_HSV, image_h, image_s, image_v, NULL);
    33 
    34     CvHistogram * histgram_3D;
    35 
    36     const int dims = 3;
    37     int bin_2 = 2;
    38     int bin_16 = 16;
    39     int bin_256 = 256;
    40 
    41     int hist_sizes[dims] = { bin_2, bin_2, bin_2 };
    42     int hist_type = CV_HIST_ARRAY;
    43     float h_range[] = { 0, 180 };
    44     float s_range[] = { 0, 255 };
    45     float v_range[] = { 0, 255 };
    46     float *hist_ranges[dims] = { h_range, s_range, v_range };
    47 
    48     histgram_3D = cvCreateHist(dims, hist_sizes, hist_type, hist_ranges, 1);
    49 
    50     IplImage *allImagePlane[dims] = { image_h, image_s, image_v };
    51 
    52     cvCalcHist(allImagePlane, histgram_3D);
    53      
    54     system("pause");
    55 
    56     cvWaitKey();
    57     cvReleaseImage(&image_Source);
    58     cvDestroyAllWindows();
    59 
    60     return 0;
    61 }
    62 
    63 void DrawHistogram(IplImage * image_hist, const CvHistogram * histogram)
    64 {
    65 
    66 
    67 }
    68 
    69 
    70  
    题目a代码
      1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
      2 //
      3 //D:\Work\Work_Programming\Source\Image\lena.jpg
      4 
      5 #include "stdafx.h"
      6 #include <cv.h>
      7 #include <highgui.h>
      8 #include <iostream>
      9 
     10 #include <opencv2/legacy/legacy.hpp>
     11 //#pragma comment(lib, "opencv_legacy2411.lib")
     12 
     13 using namespace cv;
     14 using namespace std;
     15 
     16 //函数声明-->--->-->--->-->--->-->--->//
     17 
     18 CvHistogram * Create3DHistogram(const int dims, int bins);
     19 void CreateSingleImage(IplImage * image_Src, IplImage **image_r, IplImage **image_g, IplImage **image_b);
     20 void DrawHistogram(IplImage ** image_hist, const CvHistogram * histogram, int scaleValue);
     21 
     22 //<--<--<--<--<--<--<--<--<--函数声明//
     23 
     24 int _tmain(int argc, _TCHAR* argv[])
     25 {
     26     const char * soutceFile_InDoor = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\hand_sample3.jpg";
     27     const char * soutceFile_OutDoor = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\hand_sample2.jpg";
     28     const char * soutceFile_OutDoorSun = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\hand_sample1.jpg";
     29 
     30     IplImage * image_Source_Indoor = cvLoadImage(soutceFile_InDoor, CV_LOAD_IMAGE_UNCHANGED);
     31     assert(image_Source_Indoor);
     32     IplImage * image_Source_Outdoor = cvLoadImage(soutceFile_OutDoor, CV_LOAD_IMAGE_UNCHANGED);
     33     assert(image_Source_Outdoor);
     34     IplImage * image_Source_OutdoorSun = cvLoadImage(soutceFile_OutDoorSun, CV_LOAD_IMAGE_UNCHANGED);
     35     assert(image_Source_OutdoorSun);
     36 
     37     IplImage * image_r;
     38     IplImage * image_g;
     39     IplImage * image_b;
     40 
     41     CvHistogram * histgram_3D_InDoor;
     42     CvHistogram * histgram_3D_OutDoor;
     43     CvHistogram * histgram_3D_OutDoorSun;
     44 
     45     double histCompare;
     46 
     47     const int dims = 3;
     48     int bin_N[] = { 2, 8, 16, 32, 256 };
     49     size_t length_bin_N = sizeof(bin_N) / sizeof(bin_N[0]);
     50 
     51     for (size_t i = 0; i < length_bin_N; ++i)
     52     {
     53         //室内直方图
     54         CreateSingleImage(image_Source_Indoor, &image_r, &image_g, &image_b);
     55         cvCvtPixToPlane(image_Source_Indoor, image_r, image_g, image_b, NULL);
     56         IplImage *allImagePlane[3] = { image_r, image_g, image_b };
     57 
     58         histgram_3D_InDoor = Create3DHistogram(dims, bin_N[i]);
     59         cvCalcHist(allImagePlane, histgram_3D_InDoor);
     60         cvNormalizeHist(histgram_3D_InDoor, 1.0);
     61 
     62         cvReleaseImage(&image_r);
     63         cvReleaseImage(&image_g);
     64         cvReleaseImage(&image_b);
     65 
     66         //室外直方图
     67         CreateSingleImage(image_Source_Outdoor, &image_r, &image_g, &image_b);
     68         cvCvtPixToPlane(image_Source_Outdoor, image_r, image_g, image_b, NULL);
     69         allImagePlane[0] = image_r;
     70         allImagePlane[1] = image_g;
     71         allImagePlane[2] = image_b;
     72 
     73         histgram_3D_OutDoor = Create3DHistogram(dims, bin_N[i]);
     74         cvCalcHist(allImagePlane, histgram_3D_OutDoor);
     75         cvNormalizeHist(histgram_3D_OutDoor, 1.0);
     76 
     77         cvReleaseImage(&image_r);
     78         cvReleaseImage(&image_g);
     79         cvReleaseImage(&image_b);
     80 
     81         //室外阳光直方图
     82         CreateSingleImage(image_Source_OutdoorSun, &image_r, &image_g, &image_b);
     83         cvCvtPixToPlane(image_Source_OutdoorSun, image_r, image_g, image_b, NULL);
     84         allImagePlane[0] = image_r;
     85         allImagePlane[1] = image_g;
     86         allImagePlane[2] = image_b;
     87 
     88         histgram_3D_OutDoorSun = Create3DHistogram(dims, bin_N[i]);
     89         cvCalcHist(allImagePlane, histgram_3D_OutDoorSun);
     90         cvNormalizeHist(histgram_3D_OutDoorSun, 1.0);
     91 
     92         cvReleaseImage(&image_r);
     93         cvReleaseImage(&image_g);
     94         cvReleaseImage(&image_b);
     95 
     96         if (bin_N[i] == 8)
     97         {
     98             cvNamedWindow("bin等于8时的室内直方图", CV_WINDOW_AUTOSIZE);
     99             cvNamedWindow("bin等于8时的室外直方图", CV_WINDOW_AUTOSIZE);
    100             cvNamedWindow("bin等于8时的室外阳光直方图", CV_WINDOW_AUTOSIZE);
    101 
    102             IplImage *histImage_Indoor;
    103             IplImage *histImage_Outdoor;
    104             IplImage *histImage_OutdoorSun;
    105 
    106             DrawHistogram(&histImage_Indoor, histgram_3D_InDoor, 1000);
    107             cvShowImage("bin等于8时的室内直方图", histImage_Indoor);
    108             cvReleaseImage(&histImage_Indoor);
    109 
    110             DrawHistogram(&histImage_Outdoor, histgram_3D_OutDoor, 1000);
    111             cvShowImage("bin等于8时的室外直方图", histImage_Outdoor);
    112             cvReleaseImage(&histImage_Outdoor);
    113 
    114             DrawHistogram(&histImage_OutdoorSun, histgram_3D_OutDoorSun, 1000);
    115             cvShowImage("bin等于8时的室外阳光直方图", histImage_OutdoorSun);
    116             cvReleaseImage(&histImage_OutdoorSun);
    117         }
    118             
    119         //输出匹配结果
    120         cout << "--  bin为"<<bin_N[i]<<"  --  " << endl;
    121         cout << "===============================================================================" << endl;
    122 
    123         cout << "CV_COMP_CORREL方法:数值越大越匹配,范围:完全匹配:1,完全不匹配:-1,无关联:0" << endl;
    124         cout << "-------------------------------------------------------------------------------" << endl;
    125         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoor, CV_COMP_CORREL);
    126         cout << "InDoor与OutDoor    :" << histCompare << endl;
    127         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoorSun, CV_COMP_CORREL);
    128         cout << "InDoor与OutDoorSun :" << histCompare << endl;
    129         histCompare = cvCompareHist(histgram_3D_OutDoor, histgram_3D_OutDoorSun, CV_COMP_CORREL);
    130         cout << "OutDoor与OutDoorSun:" << histCompare << endl;
    131 
    132         cout << endl;
    133 
    134         cout << "CV_COMP_CHISQR方法:数值越小越匹配,范围:0到无穷大" << endl;
    135         cout << "-------------------------------------------------------------------------------" << endl;
    136         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoor, CV_COMP_CHISQR);
    137         cout << "InDoor与OutDoor    :" << histCompare << endl;
    138         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoorSun, CV_COMP_CHISQR);
    139         cout << "InDoor与OutDoorSun :" << histCompare << endl;
    140         histCompare = cvCompareHist(histgram_3D_OutDoor, histgram_3D_OutDoorSun, CV_COMP_CHISQR);
    141         cout << "OutDoor与OutDoorSun:" << histCompare << endl;
    142 
    143         cout << endl;
    144 
    145         cout << "CV_COMP_INTERSECT方法:低分代表坏的匹配,范围:如果两个直方图都被归一化到1,则0~1" << endl;
    146         cout << "-------------------------------------------------------------------------------" << endl;
    147         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoor, CV_COMP_INTERSECT);
    148         cout << "InDoor与OutDoor    :" << histCompare << endl;
    149         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoorSun, CV_COMP_INTERSECT);
    150         cout << "InDoor与OutDoorSun :" << histCompare << endl;
    151         histCompare = cvCompareHist(histgram_3D_OutDoor, histgram_3D_OutDoorSun, CV_COMP_INTERSECT);
    152         cout << "OutDoor与OutDoorSun:" << histCompare << endl;
    153 
    154         cout << endl;
    155 
    156         cout << "CV_COMP_BHATTACHARYYA方法:低分代表好的匹配,范围:0~1" << endl;
    157         cout << "-------------------------------------------------------------------------------" << endl;
    158         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoor, CV_COMP_BHATTACHARYYA);
    159         cout << "InDoor与OutDoor    :" << histCompare << endl;
    160         histCompare = cvCompareHist(histgram_3D_InDoor, histgram_3D_OutDoorSun, CV_COMP_BHATTACHARYYA);
    161         cout << "InDoor与OutDoorSun :" << histCompare << endl;
    162         histCompare = cvCompareHist(histgram_3D_OutDoor, histgram_3D_OutDoorSun, CV_COMP_BHATTACHARYYA);
    163         cout << "OutDoor与OutDoorSun:" << histCompare << endl;
    164 
    165         cout << endl;
    166         cout << endl;
    167         cout << endl;
    168 
    169         cvReleaseHist(&histgram_3D_InDoor);
    170         cvReleaseHist(&histgram_3D_OutDoor);
    171         cvReleaseHist(&histgram_3D_OutDoorSun);
    172     }
    173 
    174     //system("pause");
    175 
    176     cvWaitKey();
    177     cvReleaseImage(&image_Source_Indoor);
    178     cvReleaseImage(&image_Source_Outdoor);
    179     cvReleaseImage(&image_Source_OutdoorSun);
    180 
    181     cvDestroyAllWindows();
    182 
    183     return 0;
    184 }
    185 
    186 CvHistogram * Create3DHistogram(const int dims, int bins)
    187 {
    188     int hist_sizes[] = { bins, bins, bins };
    189     int hist_type = CV_HIST_ARRAY;
    190     float r_range[] = { 0, 255 };
    191     float g_range[] = { 0, 255 };
    192     float b_range[] = { 0, 255 };
    193     float *hist_ranges[] = { r_range, g_range, b_range };
    194 
    195     return cvCreateHist(dims, hist_sizes, hist_type, hist_ranges, 1);
    196 }
    197 
    198 void CreateSingleImage(IplImage * image_Src, IplImage **image_r, IplImage **image_g, IplImage **image_b)
    199 {
    200     IplImage * image_temp = cvCreateImage(cvGetSize(image_Src), IPL_DEPTH_8U, 1);
    201     //image_r = &image_temp; 
    202     //如果用上面这行这种方式,编译通过,但运行崩溃,本函数结束后image_r便被释放,
    203     //因为image_temp只是一个指针变量,占用四个字节的局部变量,对它取地址即&image_temp只是这个局部指针变量的地址,函数结束后自然释放掉
    204     //但是,将使用下面这行:将image_temp指针变量所保存的地址赋值给“*image_r”,这个地址是从cvCreateImagere中turn出来的,自然不会随函数结束而释放
    205     *image_r = image_temp;
    206 
    207     *image_g = cvCloneImage(image_temp);
    208     *image_b = cvCloneImage(image_temp);
    209     cvZero(*image_r);
    210     cvZero(*image_g);
    211     cvZero(*image_b);
    212 }
    213 
    214 //目前只实现绘制三维直方图
    215 void DrawHistogram(IplImage ** image_hist, const CvHistogram * histogram,int scaleValue)
    216 {
    217     //直方图:横坐标表示各个bin,纵坐标表示各个bin归一化后的值
    218     int hist_dims = histogram->mat.dims;
    219 
    220     int bin_size1, bin_size2, bin_size3;
    221 
    222     if (hist_dims == 3)
    223     {
    224         bin_size1 = histogram->mat.dim[0].size;
    225         bin_size2 = histogram->mat.dim[1].size;
    226         bin_size3 = histogram->mat.dim[2].size;
    227     }
    228     else
    229     {
    230         return;
    231     }
    232 
    233     int bin_count = bin_size1*bin_size2*bin_size3;
    234     float max_temp;
    235     cvGetMinMaxHistValue(histogram, NULL, &max_temp);
    236     int max_value = (int)(max_temp*scaleValue) + 1;
    237     CvSize hist_imageSize = cvSize(bin_count, max_value);
    238     *image_hist = cvCreateImage(hist_imageSize, IPL_DEPTH_8U, 1);
    239     (*image_hist)->origin = 1;
    240     cvZero(*image_hist);
    241 
    242     int x;
    243     int value;
    244 
    245     for (int r = 0; r < bin_size1; ++r)
    246     {
    247         for (int g = 0; g < bin_size2; ++g)
    248         {
    249             for (int b = 0; b < bin_size3; ++b)
    250             {
    251                 x = r*(bin_size1*bin_size2) + g*bin_size2 + b;
    252                 value = (int)(cvQueryHistValue_3D(histogram, r, g, b)*scaleValue);
    253         /*        if (value == 0)
    254                 {
    255                     value = 10;
    256                 }*/
    257                 cvRectangle(*image_hist, cvPoint(x, 0), cvPoint(x, value), cvScalar(255));
    258             }
    259         }
    260     }
    261 }

      

    结果图片:

     

    要言妙道:

     ①二维直方图bin的多少是各维度bin的乘积,以h和s二维直方图来说,如果h的bin的个数为30,s的bin的个数为32,则,二维直方图的bin的个数为30×32,访问的时候要使用cvQueryHistValue_2D

    ②由于需要匹配“各种光线”下的直方图,所以,代码中将BGR图像转成了HSV图像 cvCvtColor(image_Source, image_HSV, CV_BGR2HSV); 

    ③书中Example 7-1统计的是HS直方图,即色调和饱和度,没有统计亮度,针对三种光线下的手的图像,如果统计亮度即V的直方图,三种环境下的匹配结果值肯定不匹配度很高。这点在230页有专门的讲解,为什么只选取HS两维而避开V维,是这个道理。

    ④为什么说是手的肤色直方图,从图7-6的表述来看,所谓肤色直方图即肤色所在图片的直方图,在英文版更看得出这个意思。 

    ⑤一般情况下在对比直方图之前,都应该自行进行归一化操作,因为如果不归一化,像直方图相交等概念就没有任何意义(即使运行)

  • 相关阅读:
    基于Metaweblog API 接口一键发布到国内外主流博客平台
    uva144 Student Grants
    Uva 10452
    Uva 439 Knight Moves
    Uva 352 The Seasonal War
    switch语句
    java——基础知识
    我的lua学习2
    codeforces 431 D. Random Task 组合数学
    codeforces 285 D. Permutation Sum 状压 dfs打表
  • 原文地址:https://www.cnblogs.com/tingshuixuan2012/p/4484519.html
Copyright © 2011-2022 走看看