【OpenCV】直方图对比

涉及到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;
}

以下是运行结果:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值