涉及到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;
}
以下是运行结果: