您的位置:首页 > 其它

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

2015-05-09 21:43 435 查看
提纲

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

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

程序代码:

// OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
//
//D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg

#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#include <iostream>

#include <opencv2/legacy/legacy.hpp>
//#pragma comment(lib, "opencv_legacy2411.lib")

using namespace cv;
using namespace std;

//函数声明-->--->-->--->-->--->-->--->//

CvHistogram * Create3DHistogram(const int dims, int bins);
void CreateSingleImage(IplImage * image_Src, IplImage **image_r, IplImage **image_g, IplImage **image_b);
void CreateSignatureFromHistogram(const CvHistogram * histgogram, CvMat ** signature);

//<--<--<--<--<--<--<--<--<--函数声明//

int _tmain(int argc, _TCHAR* argv[])
{
const char * soutceFile_InDoor = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第7章\\楼道1.jpg";
const char * soutceFile_OutDoor = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第7章\\楼道2.jpg";
const char * soutceFile_OutDoorSun = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第7章\\室外阳光1.jpg";

const char * coloc_1 = "楼道1";
const char * coloc_2 = "楼道2";
const char * coloc_3 = "室外阳光1";

IplImage * load_image_Source_Indoor = cvLoadImage(soutceFile_InDoor, CV_LOAD_IMAGE_UNCHANGED);
assert(load_image_Source_Indoor);
IplImage * load_image_Source_Outdoor = cvLoadImage(soutceFile_OutDoor, CV_LOAD_IMAGE_UNCHANGED);
assert(load_image_Source_Outdoor);
IplImage * load_image_Source_OutdoorSun = cvLoadImage(soutceFile_OutDoorSun, CV_LOAD_IMAGE_UNCHANGED);
assert(load_image_Source_OutdoorSun);

IplImage * image_Source_Indoor = cvCreateImage(cvGetSize(load_image_Source_Indoor), IPL_DEPTH_8U, 3);
IplImage * image_Source_Outdoor = cvCreateImage(cvGetSize(load_image_Source_Outdoor), IPL_DEPTH_8U, 3);
IplImage * image_Source_OutdoorSun = cvCreateImage(cvGetSize(load_image_Source_OutdoorSun), IPL_DEPTH_8U, 3);
cvCvtColor(load_image_Source_Indoor, image_Source_Indoor, CV_BGR2HSV);
cvCvtColor(load_image_Source_Outdoor, image_Source_Outdoor, CV_BGR2HSV);
cvCvtColor(load_image_Source_OutdoorSun, image_Source_OutdoorSun, CV_BGR2HSV);

IplImage * image_r;
IplImage * image_g;
IplImage * image_b;

CvHistogram * histgram_3D_InDoor;
CvHistogram * histgram_3D_OutDoor;
CvHistogram * histgram_3D_OutDoorSun;
CvMat * sig_Indoor, *sig_Outdoor, *sig_OutdoorSun;

double emd_result;

const int dims = 1;
int bin_N[] = { 8 }; //本题只计算bin值为8的情况
size_t length_bin_N = sizeof(bin_N) / sizeof(bin_N[0]);

for (size_t i = 0; i < length_bin_N; ++i)
{
//①
CreateSingleImage(image_Source_Indoor, &image_r, &image_g, &image_b);
cvCvtPixToPlane(image_Source_Indoor, image_r, image_g, image_b, NULL);
IplImage *allImagePlane[3] = { image_r, image_g, image_b };

histgram_3D_InDoor = Create3DHistogram(dims, bin_N[i]);
cvCalcHist(allImagePlane, histgram_3D_InDoor);
//cvNormalizeHist(histgram_3D_InDoor, 1.0);
CreateSignatureFromHistogram(histgram_3D_InDoor, &sig_Indoor);

cvReleaseImage(&image_r);
cvReleaseImage(&image_g);
cvReleaseImage(&image_b);

//②
CreateSingleImage(image_Source_Outdoor, &image_r, &image_g, &image_b);
cvCvtPixToPlane(image_Source_Outdoor, image_r, image_g, image_b, NULL);
allImagePlane[0] = image_r;
allImagePlane[1] = image_g;
allImagePlane[2] = image_b;

histgram_3D_OutDoor = Create3DHistogram(dims, bin_N[i]);
cvCalcHist(allImagePlane, histgram_3D_OutDoor);
//cvNormalizeHist(histgram_3D_OutDoor, 1.0);
CreateSignatureFromHistogram(histgram_3D_OutDoor, &sig_Outdoor);

cvReleaseImage(&image_r);
cvReleaseImage(&image_g);
cvReleaseImage(&image_b);

//③
CreateSingleImage(image_Source_OutdoorSun, &image_r, &image_g, &image_b);
cvCvtPixToPlane(image_Source_OutdoorSun, image_r, image_g, image_b, NULL);
allImagePlane[0] = image_r;
allImagePlane[1] = image_g;
allImagePlane[2] = image_b;

histgram_3D_OutDoorSun = Create3DHistogram(dims, bin_N[i]);
cvCalcHist(allImagePlane, histgram_3D_OutDoorSun);
//cvNormalizeHist(histgram_3D_OutDoorSun, 1.0);
CreateSignatureFromHistogram(histgram_3D_OutDoorSun, &sig_OutdoorSun);

cvReleaseImage(&image_r);
cvReleaseImage(&image_g);
cvReleaseImage(&image_b);

cout << "=============直方图EMD距离:0表示最精确的匹配=============" << endl << endl;
cout << "-------------“" << coloc_1 << "”与“" << coloc_2 << "”直方图EMD距离-------------" << endl;
emd_result = cvCalcEMD2(sig_Indoor, sig_Outdoor, CV_DIST_L2);
cout << emd_result << endl << endl;

cout << "-------------“" << coloc_1 << "”与“" << coloc_3 << "”直方图EMD距离-------------" << endl;
emd_result = cvCalcEMD2(sig_Indoor, sig_OutdoorSun, CV_DIST_L2);
cout << emd_result << endl << endl;

cout << "-------------“" << coloc_2 << "”与“" << coloc_3 << "”直方图EMD距离-------------" << endl;
emd_result = cvCalcEMD2(sig_Outdoor, sig_OutdoorSun, CV_DIST_L2);
cout << emd_result << endl << endl;

cvReleaseMat(&sig_Indoor);
cvReleaseMat(&sig_Outdoor);
cvReleaseMat(&sig_OutdoorSun);

cvReleaseHist(&histgram_3D_InDoor);
cvReleaseHist(&histgram_3D_OutDoor);
cvReleaseHist(&histgram_3D_OutDoorSun);
}

system("pause");

cvWaitKey();
cvReleaseImage(&image_Source_Indoor);
cvReleaseImage(&image_Source_Outdoor);
cvReleaseImage(&image_Source_OutdoorSun);

cvDestroyAllWindows();

return 0;
}

CvHistogram * Create3DHistogram(const int dims, int bins)
{
int hist_sizes[] = { bins };
int hist_type = CV_HIST_ARRAY;
float v_range[] = { 0, 255 };
float *hist_ranges[] = { v_range};

return cvCreateHist(dims, hist_sizes, hist_type, hist_ranges, 1);
}

void CreateSingleImage(IplImage * image_Src, IplImage **image_r, IplImage **image_g, IplImage **image_b)
{
IplImage * image_temp = cvCreateImage(cvGetSize(image_Src), IPL_DEPTH_8U, 1);
//image_r = &image_temp;
//如果用上面这行这种方式,编译通过,但运行崩溃,本函数结束后image_r便被释放,
//因为image_temp只是一个指针变量,占用四个字节的局部变量,对它取地址即&image_temp只是这个局部指针变量的地址,函数结束后自然释放掉
//但是,将使用下面这行:将image_temp指针变量所保存的地址赋值给“*image_r”,这个地址是从cvCreateImagere中turn出来的,自然不会随函数结束而释放
*image_r = image_temp;

*image_g = cvCloneImage(image_temp);
*image_b = cvCloneImage(image_temp);
cvZero(*image_r);
cvZero(*image_g);
cvZero(*image_b);
}

void CreateSignatureFromHistogram(const CvHistogram * histgogram, CvMat ** signature)
{
int hist_dims = histgogram->mat.dims;

int bin_size;

bin_size = histgogram->mat.dim[0].size;

int numrows = bin_size;
*signature = cvCreateMat(numrows, 2, CV_32FC1);

float bin_value;

for (int v = 0; v < bin_size; ++v)
{
bin_value = cvQueryHistValue_1D(histgogram, v);
cvSet2D(*signature, v, 0, cvScalar(bin_value));
cvSet2D(*signature, v, 1, cvScalar(v));
}
}


结果图片:









要言妙道:

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

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

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