涉及到OpenCV中图像的复制、合并、直方图、绘制矩形、直方图对比等知识点。
- int main()
- {
- IplImage *srcImg = cvLoadImage("J:\\baboon.jpg"); //尺寸:512*512
- IplImage *dstImg = cvLoadImage("J:\\baboon_rg.jpg");//尺寸:512*512//图像从baboon中抽取红、绿两个通道合并而成
- IplImage *gray_srcImg = cvCreateImage(cvGetSize(srcImg), IPL_DEPTH_8U, 1);
- IplImage *gray_dstImg = cvCreateImage(cvGetSize(dstImg), 8, 1);
- cvCvtColor(srcImg, gray_srcImg, CV_BGR2GRAY);
- cvCvtColor(dstImg, gray_dstImg, CV_BGR2GRAY);
- int dims = 1;
- int hist_size = 256;
- float range[] = {0, 255};
- float *ranges[] = {range};
- CvHistogram *gray_src_hist = cvCreateHist(dims, &hist_size, CV_HIST_ARRAY, ranges, 1);
- CvHistogram *gray_dst_hist = cvCreateHist(dims, &hist_size, CV_HIST_ARRAY, ranges, 1);
- cvCalcHist(&gray_srcImg, gray_src_hist, 0, 0);
- cvCalcHist(&gray_dstImg, gray_dst_hist, 0, 0);
- cvNormalizeHist(gray_src_hist, 1.0);
- cvNormalizeHist(gray_dst_hist, 1.0);
- double ret1 = cvCompareHist(gray_src_hist, gray_dst_hist, CV_COMP_CORREL);
- cout << "相关\tCV_COMP_CORREL\t\t" << ret1 << "\t\t[-1,1]值越大匹配度越高" << endl;
- double ret2 = cvCompareHist(gray_src_hist, gray_dst_hist, CV_COMP_CHISQR);
- cout << "卡方\tCV_COMP_CHISQR\t\t" << ret2 << "\t[0,∞]值越小匹配度越高" << endl;
- double ret3 = cvCompareHist(gray_src_hist, gray_dst_hist, CV_COMP_INTERSECT);
- cout << "相交\tCV_COMP_INTERSECT\t" << ret3 << "\t[0,1](归一化)值越大匹配度越高" << endl;
- double ret4 = cvCompareHist(gray_src_hist, gray_dst_hist, CV_COMP_BHATTACHARYYA);
- cout << "距离\tCV_COMP_BHATTACHARYYA\t" << ret4 << "\t[0,1](归一化)值越小匹配度越高" << endl;
- const int width = 256;
- const int height = 256;
- const int imgCount = 4;//显示的图像共3种:原图、灰度图、直方图(w:512)
- CvSize size = cvSize(width * imgCount, height);
- //显示可视化图像、直方图 -- src
- IplImage *src_hist_img = cvCreateImage(size, 8, srcImg->nChannels);//最终合成的图像
- cvZero(src_hist_img);
- IplImage *srcImg2 = cvCreateImage(cvSize(width, height), 8 ,3);//将原始图像缩小一半
- cvZero(srcImg2);
- cvResize(srcImg, srcImg2, CV_INTER_LINEAR);
- //合并/复制源图像
- cvSetImageROI(src_hist_img, cvRect(0, 0, width, height));
- cvCopyImage(srcImg2, src_hist_img);
- cvResetImageROI(src_hist_img);
- cvReleaseImage(&srcImg2);
- //合并灰度图像
- IplImage *gray_3_img = cvCreateImage(cvGetSize(gray_srcImg), 8, 3);
- cvZero(gray_3_img);
- cvCvtColor(gray_srcImg, gray_3_img, CV_GRAY2BGR);
- IplImage *gray_3_img2 = cvCreateImage(cvSize(width, height), 8, 3);
- cvResize(gray_3_img, gray_3_img2, CV_INTER_LINEAR);//缩小一半
- cvSetImageROI(src_hist_img, cvRect(width, 0, width, height));
- cvCopyImage(gray_3_img2, src_hist_img);
- cvResetImageROI(src_hist_img);
- cvReleaseImage(&gray_3_img);
- cvReleaseImage(&gray_3_img2);
- //合并直方图
- int scale = 2;
- IplImage *hist_img = cvCreateImage(cvSize(width * scale, height), 8, 3);//创建直方图图像
- cvZero(hist_img);
- float max_value = 0;
- cvGetMinMaxHistValue(gray_src_hist, 0, &max_value, 0, 0);
- for (int i = 0; i < hist_size; i++)
- {
- float bin_val = cvQueryHistValue_1D(gray_src_hist, i);
- int intensity = cvRound(bin_val*hist_size / max_value);//要绘制的高度
- cvRectangle(hist_img,//矩形画在直方图图像内
- cvPoint(i*scale, hist_size),//矩形对角线中的一个点
- cvPoint((i + 1) * scale - 1, hist_size - intensity),//矩形对角线中的另一个点
- CV_RGB(255, 255, 255));
- }
- cvSetImageROI(src_hist_img, cvRect(width * 2, 0, width * scale, height));
- cvCopyImage(hist_img, src_hist_img);
- cvResetImageROI(src_hist_img);
- cvReleaseImage(&hist_img);
- cvNamedWindow("1");
- cvShowImage("1", src_hist_img);
- //显示可视化图像、直方图 -- dst
- IplImage *dst_hist_img = cvCreateImage(size, 8, dstImg->nChannels);//最终合成的图像
- cvZero(dst_hist_img);
- IplImage *dstImg2 = cvCreateImage(cvSize(width, height), 8, 3);//先将原始图片缩小一半
- cvZero(dstImg2);
- cvResize(dstImg, dstImg2, CV_INTER_LINEAR);
- //合并/复制源图像
- cvSetImageROI(dst_hist_img, cvRect(0, 0, width, height));
- cvCopyImage(dstImg2, dst_hist_img);
- cvResetImageROI(dst_hist_img);
- cvReleaseImage(&dstImg2);
- //合并灰度图像
- IplImage *gray_3_dst_img = cvCreateImage(cvGetSize(gray_srcImg), 8, 3);
- cvZero(gray_3_dst_img);
- cvCvtColor(gray_srcImg, gray_3_dst_img, CV_GRAY2BGR);
- IplImage *gray_3_dst_img2 = cvCreateImage(cvSize(width, height), 8, 3);
- cvResize(gray_3_dst_img, gray_3_dst_img2, CV_INTER_LINEAR);//缩小一半
- cvSetImageROI(dst_hist_img, cvRect(width, 0, width, height));
- cvCopyImage(gray_3_dst_img2, dst_hist_img);
- cvResetImageROI(dst_hist_img);
- cvReleaseImage(&gray_3_dst_img);
- cvReleaseImage(&gray_3_dst_img2);
- //合并直方图
- IplImage *hist_dst_img = cvCreateImage(cvSize(width * scale, height), 8, 3);//创建直方图图像
- cvZero(hist_dst_img);
- float max_value_dst = 0;
- cvGetMinMaxHistValue(gray_dst_hist, 0, &max_value_dst, 0, 0);
- for (int i = 0; i < hist_size; i++)
- {
- float bin_val = cvQueryHistValue_1D(gray_dst_hist, i);
- int intensity = cvRound(bin_val*hist_size / max_value_dst);//要绘制的高度
- cvRectangle(hist_dst_img,//矩形画在直方图图像内
- cvPoint(i*scale, hist_size),//矩形对角线中的一个点
- cvPoint((i + 1) * scale - 1, hist_size - intensity),//矩形对角线中的另一个点
- CV_RGB(255, 255, 255));
- }
- cvSetImageROI(dst_hist_img, cvRect(width * 2, 0, width * scale, height));
- cvCopyImage(hist_dst_img, dst_hist_img);
- cvResetImageROI(dst_hist_img);
- cvReleaseImage(&hist_dst_img);
- cvNamedWindow("2");
- cvShowImage("2", dst_hist_img);
- cvWaitKey(0);
- cvDestroyAllWindows();
- cvReleaseImage(&srcImg);
- cvReleaseImage(&dstImg);
- cvReleaseImage(&gray_srcImg);
- cvReleaseImage(&gray_dstImg);
- cvReleaseImage(&src_hist_img);
- return 0;
- }
以下是运行结果: