java怎么实现直方图均衡化_实现直方图均衡化(java+opencv)

本文介绍了直方图均衡化技术,这是一种用于增强图像对比度的方法。直方图均衡化通过改变图像的灰度分布,将原本集中在狭窄范围的灰度级展宽,从而提高图像清晰度。文章解释了直方图的概念,展示了如何用Java和OpenCV库计算和显示直方图,并提供了一个简单的Java代码示例,演示了如何进行直方图均衡化处理。
摘要由CSDN通过智能技术生成

什么是直方图均衡化?

直方图均衡化是一种简单有效的图像增强技术,通过改变图像的直方图来改变图像中各像素的灰度,主要用于增强动态范围偏小的图像的对比度。原始图像由于其灰度分布可能集中在较窄的区间,造成图像不够清晰。例如,过曝光图像的灰度级集中在高亮度范围内,而曝光不足将使图像灰度级集中在低亮度范围内。采用直方图均衡化,可以把原始图像的直方图变换为均匀分布(均衡)的形式,这样就增加了像素之间灰度值差别的动态范围,从而达到增强图像整体对比度的效果。换言之,直方图均衡化的基本原理是:对在图像中像素个数多的灰度值(即对画面起主要作用的灰度值)进行展宽,而对像素个数少的灰度值(即对画面不起主要作用的灰度值)进行归并,从而增大对比度,使图像清晰,达到增强的目的。举个例子,如图中所示,左图为原始图像,右图为直方图均衡化后的图像。

个人的理解是,直方图可以提高图像的对比度,对于原本对比度较低的图像效果比较明显。

8e159156b8d217a7b9067907e4fe101b.png

直方图的概念

对一幅灰度图像,其直方图反映了该图像中不同灰度级出现的统计情况。图2给出了一个直方图的示例,其中图(a)是一幅图像,其灰度直方图可表示为图(b),其中横轴表示图像的各灰度级,纵轴表示图像中各灰度级像素的个数。(需要注意,灰度直方图表示了在图像中各个单独灰度级的分布,而图像对比度则取决于相邻近像素之间灰度级的关系。)

e268a34b0b04d24268a9884aca70239d.png

严格地说,图像的灰度直方图是一个一维的离散函数,可写成:

2543c22b97ff88187b320260f9e3eedd.png                 

9b3e4f2f7aa19e47e9878e0ae023582d.png(公式1)

式中,是图像中灰度级为的像素的个数。直方图的每一列(称为bin)的高度对应。直方图提供了原图中各种灰度值分布的情况,也可以说直方图给出了一幅图像所有灰度值的整体描述。直方图的均值和方差也是图像灰度的均值和方差。图像的视觉效果与其直方图有对应关系,或者说,直方图的形状和改变对图像有很大的影响。

在直方图的基础上,进一步定义归一化的直方图为灰度级出现的相对频率

35cb5a4bbac0910219f5dd25406572a6.png。即:

65100d4b4fc3476ff71bba0663a9db10.png      (公式2)

式中,表示图像的像素的总数,是图像中灰度级为的像素的个数。

直方图均衡化的步骤

99676016a76f5bd8ccb8ddc18493a278.png

使用java实现直方图均衡化

importjava.util.LinkedList;importjava.util.List;importorg.opencv.core.Core;importorg.opencv.core.CvType;importorg.opencv.core.Mat;importorg.opencv.core.MatOfFloat;importorg.opencv.core.MatOfInt;importorg.opencv.core.Scalar;importorg.opencv.highgui.HighGui;importorg.opencv.imgcodecs.Imgcodecs;importorg.opencv.imgproc.Imgproc;public classhuiduhua {//静态代码块加载动态链接库

static{

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

}public static voidmain(String[] args) {/** IMREAD_UNCHANGED = -1 :不进行转化,比如保存为了16位的图片,读取出来仍然为16位。

* IMREAD_GRAYSCALE = 0 :进行转化为灰度图,比如保存为了16位的图片,读取出来为8位,类型为CV_8UC1。

* IMREAD_COLOR = 1 :进行转化为三通道图像。

* IMREAD_ANYDEPTH = 2 :如果图像深度为16位则读出为16位,32位则读出为32位,其余的转化为8位。

* IMREAD_ANYCOLOR = 4 :图像以任何可能的颜色格式读取

* IMREAD_LOAD_GDAL = 8 :使用GDAL驱动读取文件,GDAL(Geospatial Data Abstraction

* Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。

* 它还有一系列命令行工具来进行数据转换和处理。*/Mat src= Imgcodecs.imread("./data/huiduhua.png",0);//Imgproc.resize(src, src, new Size(src.cols()/2,src.rows()/2));

HighGui.imshow("原图", src);

HighGui.waitKey();

ImgCalcHist(src,"原图直方图");

Mat dst= newMat();//直方图均衡化,该算法对亮度进行归一化并增加图像的对比度。

Imgproc.equalizeHist(src,dst);

HighGui.imshow("直方图均衡化", dst);

HighGui.waitKey();

ImgCalcHist(dst,"直方图均衡化后的直方图");

}/*** 直方图

*@paramsrc

*@paramwindowName*/

public static voidImgCalcHist(Mat src,String windowName) {

List matList = new LinkedList();

matList.add(src);

Mat histogram= newMat();

MatOfFloat ranges=new MatOfFloat(0,256);

MatOfInt histSize= new MatOfInt(300);/** 计算直方图

* List images:输入图像

* MatOfInt channels:需要统计直方图的第几通道

* Mat mask:掩膜,,计算掩膜内的直方图

* Mat hist:输出的直方图数组

* MatOfInt histSize:指的是直方图分成多少个区间,就是bin的个数

* MatOfFloat ranges: 统计像素值得区间*/Imgproc.calcHist(matList,new MatOfInt(0),newMat(),histogram,histSize ,ranges);//创建直方图面板

Mat histImage = Mat.zeros( 150, (int)histSize.get(0, 0)[0], CvType.CV_8UC1);//归一化直方图 详见https://blog.csdn.net/ren365880/article/details/103923813

Core.normalize(histogram, histogram, 1, histImage.rows() , Core.NORM_MINMAX, -1, newMat() );//绘制直线 详见:https://blog.csdn.net/ren365880/article/details/103952856

for( int i = 0; i < (int)histSize.get(0, 0)[0]; i++){

Imgproc.line(histImage,new org.opencv.core.Point(i, histImage.rows()),new org.opencv.core.Point(i, histImage.rows()-Math.round( histogram.get(i,0)[0])) ,new Scalar( 255, 255, 255),1, 8, 0);

}

HighGui.imshow(windowName, histImage);

HighGui.waitKey();

}

}

效果:

903b3a4b9a257223a5360296c1680d4e.png

90cb0f8361299bd9267212ddafd5a516.png

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分布图像的像素值来扩展图像的动态范围,使得图像中的像素值更加均匀分布。这样可以提高图像的亮度和对比度,使得图像更加清晰和易于分析。 在Java中,你可以使用OpenCV库来实现直方图均衡化。下面是一个示例代码: ```java import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.CvType; import org.opencv.core.MatOfByte; import org.opencv.core.MatOfInt; import org.opencv.core.MatOfFloat; import org.opencv.core.Size; import org.opencv.core.CvType; import org.opencv.core.Scalar; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.core.CLAHE; public class HistogramEqualization { public static void main(String[] args) { // 加载OpenCV库 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 读取图像 Mat image = Imgcodecs.imread("path/to/your/image.jpg"); // 将图像转换为灰度图像 Mat grayImage = new Mat(); Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY); // 应用直方图均衡化 Mat equalizedImage = new Mat(); Imgproc.equalizeHist(grayImage, equalizedImage); // 显示原始图像和均衡化后的图像 Imgcodecs.imwrite("path/to/your/equalized_image.jpg", equalizedImage); } } ``` 请注意,你需要将代码中的`"path/to/your/image.jpg"`替换为你要处理的图像的路径,并将`"path/to/your/equalized_image.jpg"`替换为保存均衡化后图像的路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值