图像增强算法实现--直方图的均衡化

</pre>(1)算法描述:</h1><p><span style="color:rgb(51,51,51)"><span style="white-space:pre"></span><span style="white-space:pre">	</span>直方图均衡化的基本思想是对图像中像素个数多的灰度级进行展宽,而对图像中像素个数少的灰度进行压缩,从而扩展像原取值的动态范围,提高了对比度和灰度色调的变化,使图像更加清晰。彩色直方图的均衡化,可以将图像分离为三个信道,分别对每个信道均衡化后再进行信道合并,然后将图像转换成直方图。本程序写了<span style="font-family:Arial">cvShowHist</span><span style="font-family:宋体">函数进行实现,先将输入图像转换到</span><span style="font-family:Arial">HSV</span><span style="font-family:宋体">颜色空间,在根据</span><span style="font-family:Arial">H</span><span style="font-family:宋体">,</span><span style="font-family:Arial">S</span><span style="font-family:宋体">两个平面的数据统计直方图,获取直方图统计的最大值,创建直方图,获取直方图中的统计次数,来计算显示图像中的高度,获取当前直方图的代表颜色,将其转换回</span><span style="font-family:Arial">RGB</span><span style="font-family:宋体">进行绘制。</span></span></p><h2>(2)实验结果,界面图:</h2><p>整体运行截图:</p><p> </p><p> <img src="https://img-blog.csdn.net/20160316193400357?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></p><p> </p><p style="text-align:center">左上:原始彩色图像    右上:均衡化后图像</p><p style="text-align:center">左下:原始直方图      右下:均衡化直方图</p><p> </p><p></p><h2>(3)关键代码:</h2><div><pre name="code" class="cpp">#include <fstream>
#include <iostream>
#include <string>
#include <opencv/cv.h>
#include <opencv/highgui.h> 
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define cvQueryHistValue_2D( hist, idx0, idx1 )   cvGetReal2D( (hist)->bins, (idx0), (idx1) )

IplImage* cvShowHist(IplImage* src)
{
	IplImage* hsv = cvCreateImage(cvGetSize(src), 8, 3);
	IplImage* h_plane = cvCreateImage(cvGetSize(src), 8, 1);
	IplImage* s_plane = cvCreateImage(cvGetSize(src), 8, 1);
	IplImage* v_plane = cvCreateImage(cvGetSize(src), 8, 1);
	IplImage* planes[] = { h_plane, s_plane };

	int h_bins = 16, s_bins = 8;
	int hist_size[] = { h_bins, s_bins };
	float h_ranges[] = { 0, 180 };

	float s_ranges[] = { 0, 255 };
	float* ranges[] = { h_ranges, s_ranges };

	//输入图像转换到HSV颜色空间
	cvCvtColor(src, hsv, CV_BGR2HSV);
	cvSplit(hsv, h_plane, s_plane, v_plane, 0);

	CvHistogram * hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
	cvCalcHist(planes, hist, 0, 0);

	float max_value;
	cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0);

	int height = 240;
	int width = (h_bins*s_bins * 6);
	IplImage* hist_img = cvCreateImage(cvSize(width, height), 8, 3);
	cvZero(hist_img);
	IplImage * hsv_color = cvCreateImage(cvSize(1, 1), 8, 3);
	IplImage * rgb_color = cvCreateImage(cvSize(1, 1), 8, 3);
	int bin_w = width / (h_bins * s_bins);
	for (int h = 0; h < h_bins; h++)
	{
		for (int s = 0; s < s_bins; s++)
		{
			int i = h*s_bins + s;
			float bin_val = cvQueryHistValue_2D(hist, h, s);
			int intensity = cvRound(bin_val*height / max_value);

			cvSet2D(hsv_color, 0, 0, cvScalar(h*180.f / h_bins, s*255.f / s_bins, 255, 0));
			cvCvtColor(hsv_color, rgb_color, CV_HSV2BGR);
			CvScalar color = cvGet2D(rgb_color, 0, 0);

			cvRectangle(hist_img, cvPoint(i*bin_w, height),
				cvPoint((i + 1)*bin_w, height - intensity),
				color, -1, 8, 0);
		}
	}
	return hist_img;
}

void myShowHist(IplImage* image1, IplImage* image2)
{
	IplImage* hist_image1 = cvShowHist(image1);
	IplImage* hist_image2 = cvShowHist(image2);

	cvNamedWindow("原始直方图", 1);
	cvShowImage("原始直方图", hist_image1);

	cvNamedWindow("均衡化直方图", 1);
	cvShowImage("均衡化直方图", hist_image2);

	cvSaveImage("原始直方图.jpg", hist_image1);
	cvSaveImage("均衡化直方图.jpg", hist_image2);
}

int main()
{
	//对彩色图像进行均衡化
	IplImage * image = cvLoadImage("OpenCvDemo.BMP");
	IplImage* eqlimage = cvCreateImage(cvGetSize(image), image->depth, 3);
	//信道分离
	IplImage* redImage = cvCreateImage(cvGetSize(image), image->depth, 1);
	IplImage* greenImage = cvCreateImage(cvGetSize(image), image->depth, 1);
	IplImage* blueImage = cvCreateImage(cvGetSize(image), image->depth, 1);
	//用 cvSplit 函数分解图像到单个色彩通道上
	cvSplit(image, blueImage, greenImage, redImage, NULL);
	//用cvEqualizeHist函数分别均衡化每个信道
	cvEqualizeHist(redImage, redImage);
	cvEqualizeHist(greenImage, greenImage);
	cvEqualizeHist(blueImage, blueImage);
	//将信道合并
	cvMerge(blueImage, greenImage, redImage, NULL, eqlimage);

	cvNamedWindow("原始彩色图像", 1);
	cvShowImage("原始彩色图像", image);
	cvNamedWindow("均衡化后图像", 1);
	cvShowImage("均衡化后图像", eqlimage);
	cvSaveImage("均衡化后图像.bmp", eqlimage);

	myShowHist(image, eqlimage);
	cvWaitKey(0);
	cvDestroyWindow("source");
	cvDestroyWindow("result");
	cvReleaseImage(&image);
	cvReleaseImage(&eqlimage);

Return(0);
}

(4)}完成作业体会,总结:

这个作业是第一次使用opencv,觉得今天遇到的最大的困难是opencv环境的配置。尝试过两种方法。导入属性表直接配置和手动配置,遇见的问题都是“未定义标识符:opencv_calib3d300.lib”,“未定义标识符:opencv_world300.lib”之类的。后来才发现,问题在于库目录的路径不对。

而对于彩色直方图的均衡化作业来说,网上有特别多的博客可以参考。而opencv是一个很强大的计算机视觉库,很多函数都可以直接调用。例如灰度图象直方图均衡化函数cvEqualizeHist(),将几个单通道数组合并成多通道数组的函数cvMerge().等等。其实整个程序最大的难题在于将图像转换成直方图。本程序写了cvShowHist函数进行实现,先将输入图像转换到HSV颜色空间,在根据HS两个平面的数据统计直方图,获取直方图统计的最大值,创建直方图,获取直方图中的统计次数,来计算显示图像中的高度,获取当前直方图的代表颜色,将其转换回RGB进行绘制。由于是第一次接触opencv,很多函数都是在摸索中现学现用。完成本次程序,很有成就感,也学到了很多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值