【练习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明显很大
③
相关文章推荐
- 直方图 陆地移动距离 cvCalcEMD2 基于HSV的HS
- 直方图 陆基移动距离 cvCalcEMD2 基于BGR
- 关于使用cvCalcEMD2计算两个直方图间最小工作距离的限制(Why cvCalcEMD2 Throw Insufficient Memory Exception)
- 关于使用cvCalcEMD2计算两个直方图间最小工作距离的限制(Why cvCalcEMD2 Throw Insufficient Memory Exception)
- 基于陆地移动距离(EMD)的彩色图像直方图距离计算
- 【练习7.3】从直方图创建signature、计算两个直方图的EMD距离
- 根据条件判断使用不同的class
- 【Java/Android性能优5】 Android ImageCache图片缓存,使用简单,支持预取,支持多种缓存算法,支持不同网络类型,扩展性强
- 【Java/Android性能优 6】Android 图片SD卡缓存 使用简单 支持预取 支持多种缓存算法 支持不同网络类型 支持序列化
- 图像检索:一维直方图+EMD距离
- Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解
- Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解
- 【练习5.1】使用cvSmooth实现不同平滑处理方法的效果以及不同的平滑窗口对处理效果的影响
- 【练习5.2】使用中心为255的图片对比高斯滤波器的平滑效果
- 使用session在不同页面之间传递参数,sqldatasource按条件查询
- 【练习8.6】使用不同参数值观察cvFindDominantPoints寻找关键点的效果
- 【练习8.10】直接使用cvFindContour的结果图片和cvDrawContour的方式提取Hu矩,观察在图片缩放或旋转时的稳定性
- 移动WEB布局使用less语法之视网膜屏幕如何来解决图片像素问题
- html+css使用空白标签巧妙实现不同尺寸的图片在容器里垂直居中的方法
- 线程练习3---使用各种不同的类型的执行器重复练习1