• 【练习7.4】使用直方图陆地移动距离EMD区分不同光线条件下的图片cvCalcEMD2


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

      

    题目要求:

     设计一个直方图,可以判断给定的图像是在哪种光线条件下被捕捉到的。

    程序代码:

      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 CreateSignatureFromHistogram(const CvHistogram * histgogram, CvMat ** signature);
     21 
     22 //<--<--<--<--<--<--<--<--<--函数声明//
     23 
     24 int _tmain(int argc, _TCHAR* argv[])
     25 {
     26     const char * soutceFile_InDoor = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\楼道1.jpg";
     27     const char * soutceFile_OutDoor = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\楼道2.jpg";
     28     const char * soutceFile_OutDoorSun = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第7章\室外阳光1.jpg";
     29 
     30     const char * coloc_1 = "楼道1";
     31     const char * coloc_2 = "楼道2";
     32     const char * coloc_3 = "室外阳光1";
     33     
     34     IplImage * load_image_Source_Indoor = cvLoadImage(soutceFile_InDoor, CV_LOAD_IMAGE_UNCHANGED);
     35     assert(load_image_Source_Indoor);
     36     IplImage * load_image_Source_Outdoor = cvLoadImage(soutceFile_OutDoor, CV_LOAD_IMAGE_UNCHANGED);
     37     assert(load_image_Source_Outdoor);
     38     IplImage * load_image_Source_OutdoorSun = cvLoadImage(soutceFile_OutDoorSun, CV_LOAD_IMAGE_UNCHANGED);
     39     assert(load_image_Source_OutdoorSun);
     40 
     41     IplImage * image_Source_Indoor = cvCreateImage(cvGetSize(load_image_Source_Indoor), IPL_DEPTH_8U, 3);
     42     IplImage * image_Source_Outdoor = cvCreateImage(cvGetSize(load_image_Source_Outdoor), IPL_DEPTH_8U, 3);
     43     IplImage * image_Source_OutdoorSun = cvCreateImage(cvGetSize(load_image_Source_OutdoorSun), IPL_DEPTH_8U, 3);
     44     cvCvtColor(load_image_Source_Indoor, image_Source_Indoor, CV_BGR2HSV);
     45     cvCvtColor(load_image_Source_Outdoor, image_Source_Outdoor, CV_BGR2HSV);
     46     cvCvtColor(load_image_Source_OutdoorSun, image_Source_OutdoorSun, CV_BGR2HSV);
     47 
     48     IplImage * image_r;
     49     IplImage * image_g;
     50     IplImage * image_b;
     51 
     52     CvHistogram * histgram_3D_InDoor;
     53     CvHistogram * histgram_3D_OutDoor;
     54     CvHistogram * histgram_3D_OutDoorSun;
     55     CvMat * sig_Indoor, *sig_Outdoor, *sig_OutdoorSun;
     56 
     57     double emd_result;
     58 
     59     const int dims = 1;
     60     int bin_N[] = { 8 }; //本题只计算bin值为8的情况
     61     size_t length_bin_N = sizeof(bin_N) / sizeof(bin_N[0]);
     62 
     63     for (size_t i = 0; i < length_bin_N; ++i)
     64     {
     65         //
     66         CreateSingleImage(image_Source_Indoor, &image_r, &image_g, &image_b);
     67         cvCvtPixToPlane(image_Source_Indoor, image_r, image_g, image_b, NULL);
     68         IplImage *allImagePlane[3] = { image_r, image_g, image_b };
     69 
     70         histgram_3D_InDoor = Create3DHistogram(dims, bin_N[i]);
     71         cvCalcHist(allImagePlane, histgram_3D_InDoor);
     72         //cvNormalizeHist(histgram_3D_InDoor, 1.0);
     73         CreateSignatureFromHistogram(histgram_3D_InDoor, &sig_Indoor);
     74 
     75         cvReleaseImage(&image_r);
     76         cvReleaseImage(&image_g);
     77         cvReleaseImage(&image_b);
     78 
     79         //
     80         CreateSingleImage(image_Source_Outdoor, &image_r, &image_g, &image_b);
     81         cvCvtPixToPlane(image_Source_Outdoor, image_r, image_g, image_b, NULL);
     82         allImagePlane[0] = image_r;
     83         allImagePlane[1] = image_g;
     84         allImagePlane[2] = image_b;
     85 
     86         histgram_3D_OutDoor = Create3DHistogram(dims, bin_N[i]);
     87         cvCalcHist(allImagePlane, histgram_3D_OutDoor);
     88         //cvNormalizeHist(histgram_3D_OutDoor, 1.0);
     89         CreateSignatureFromHistogram(histgram_3D_OutDoor, &sig_Outdoor);
     90 
     91         cvReleaseImage(&image_r);
     92         cvReleaseImage(&image_g);
     93         cvReleaseImage(&image_b);
     94 
     95         //
     96         CreateSingleImage(image_Source_OutdoorSun, &image_r, &image_g, &image_b);
     97         cvCvtPixToPlane(image_Source_OutdoorSun, image_r, image_g, image_b, NULL);
     98         allImagePlane[0] = image_r;
     99         allImagePlane[1] = image_g;
    100         allImagePlane[2] = image_b;
    101 
    102         histgram_3D_OutDoorSun = Create3DHistogram(dims, bin_N[i]);
    103         cvCalcHist(allImagePlane, histgram_3D_OutDoorSun);
    104         //cvNormalizeHist(histgram_3D_OutDoorSun, 1.0);
    105         CreateSignatureFromHistogram(histgram_3D_OutDoorSun, &sig_OutdoorSun);
    106 
    107         cvReleaseImage(&image_r);
    108         cvReleaseImage(&image_g);
    109         cvReleaseImage(&image_b);
    110 
    111         cout << "=============直方图EMD距离:0表示最精确的匹配=============" << endl << endl;
    112         cout << "-------------“" << coloc_1 << "”与“" << coloc_2 << "”直方图EMD距离-------------" << endl;
    113         emd_result = cvCalcEMD2(sig_Indoor, sig_Outdoor, CV_DIST_L2);
    114         cout << emd_result << endl << endl;
    115 
    116         cout << "-------------“" << coloc_1 << "”与“" << coloc_3 << "”直方图EMD距离-------------" << endl;
    117         emd_result = cvCalcEMD2(sig_Indoor, sig_OutdoorSun, CV_DIST_L2);
    118         cout << emd_result << endl << endl;
    119 
    120         cout << "-------------“" << coloc_2 << "”与“" << coloc_3 << "”直方图EMD距离-------------" << endl;
    121         emd_result = cvCalcEMD2(sig_Outdoor, sig_OutdoorSun, CV_DIST_L2);
    122         cout << emd_result << endl << endl;
    123 
    124         cvReleaseMat(&sig_Indoor);
    125         cvReleaseMat(&sig_Outdoor);
    126         cvReleaseMat(&sig_OutdoorSun);
    127 
    128         cvReleaseHist(&histgram_3D_InDoor);
    129         cvReleaseHist(&histgram_3D_OutDoor);
    130         cvReleaseHist(&histgram_3D_OutDoorSun);
    131     }
    132 
    133     system("pause");
    134 
    135     cvWaitKey();
    136     cvReleaseImage(&image_Source_Indoor);
    137     cvReleaseImage(&image_Source_Outdoor);
    138     cvReleaseImage(&image_Source_OutdoorSun);
    139 
    140     cvDestroyAllWindows();
    141 
    142     return 0;
    143 }
    144 
    145 CvHistogram * Create3DHistogram(const int dims, int bins)
    146 {
    147     int hist_sizes[] = { bins };
    148     int hist_type = CV_HIST_ARRAY;
    149     float v_range[] = { 0, 255 };
    150     float *hist_ranges[] = { v_range};
    151 
    152     return cvCreateHist(dims, hist_sizes, hist_type, hist_ranges, 1);
    153 }
    154 
    155 void CreateSingleImage(IplImage * image_Src, IplImage **image_r, IplImage **image_g, IplImage **image_b)
    156 {
    157     IplImage * image_temp = cvCreateImage(cvGetSize(image_Src), IPL_DEPTH_8U, 1);
    158     //image_r = &image_temp; 
    159     //如果用上面这行这种方式,编译通过,但运行崩溃,本函数结束后image_r便被释放,
    160     //因为image_temp只是一个指针变量,占用四个字节的局部变量,对它取地址即&image_temp只是这个局部指针变量的地址,函数结束后自然释放掉
    161     //但是,将使用下面这行:将image_temp指针变量所保存的地址赋值给“*image_r”,这个地址是从cvCreateImagere中turn出来的,自然不会随函数结束而释放
    162     *image_r = image_temp;
    163 
    164     *image_g = cvCloneImage(image_temp);
    165     *image_b = cvCloneImage(image_temp);
    166     cvZero(*image_r);
    167     cvZero(*image_g);
    168     cvZero(*image_b);
    169 }
    170 
    171 void CreateSignatureFromHistogram(const CvHistogram * histgogram, CvMat ** signature)
    172 {
    173     int hist_dims = histgogram->mat.dims;
    174 
    175     int bin_size;
    176 
    177     bin_size = histgogram->mat.dim[0].size;
    178 
    179     int numrows = bin_size;
    180     *signature = cvCreateMat(numrows, 2, CV_32FC1);
    181 
    182     float bin_value;
    183  
    184      
    185     for (int v = 0; v < bin_size; ++v)
    186     {
    187         bin_value = cvQueryHistValue_1D(histgogram, v);
    188         cvSet2D(*signature, v, 0, cvScalar(bin_value));
    189         cvSet2D(*signature, v, 1, cvScalar(v));
    190     }
    191 }

    结果图片:

    要言妙道:

     ①目的是判断光线条件,所以,建一个HSV图像的V的直方图,作为“参考直方图”,其它图像的V直方图与参考直方图计算EMD距离,如果在一个范围内,则表示实在该光线条件下

    ②共三个输入图像,第一个和第二个选择同一光线条件下的,第三个图像选择其它光线条件,可以看出,第一和第二个的EMD距离很小,第一第三或第二第三的EMD明显很大

  • 相关阅读:
    ASP.NET MVC+LINQ开发一个图书销售站点(4):创建一个ASP.NET MVC应用的原型
    ASP.NET MVC+LINQ开发一个图书销售站点(9):编辑目录
    ASP.NET MVC+LINQ开发一个图书销售站点(6):创建数据层
    Linq to SQL Dynamic 动态查询
    RUP简介
    ASP.NET MVC+LINQ开发一个图书销售站点(7):图书分类管理
    ASP.NET MVC+LINQ开发一个图书销售站点(3):建立数据库
    ASP.NET MVC+LINQ开发一个图书销售站点(11):图书管理
    ASP.NET MVC+LINQ开发一个图书销售站点(10):作者管理
    MSDTC不能启动的一个解决方法
  • 原文地址:https://www.cnblogs.com/tingshuixuan2012/p/4491242.html
Copyright © 2020-2023  润新知