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的表述来看,所谓肤色直方图即肤色所在图片的直方图,在英文版更看得出这个意思。 

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

  • 相关阅读:
    oc结构
    iOS分类
    iOS协议
    缓存无底洞现象
    数据库备份,恢复
    PHP邮件发送库:Swiftmailer
    PHP分页组件:Paginator
    PHP验证码类
    PHP日期和时间处理组件-Carbon
    composer的一些操作
  • 原文地址:https://www.cnblogs.com/tingshuixuan2012/p/4484519.html
Copyright © 2011-2022 走看看