java输入数组打印直方图_[OpenCV学习日记-java]-15-图像直方图

本文介绍了如何使用Java和OpenCV计算与显示图像直方图,包括直方图的计算、显示、均衡化以及直方图的比较方法,如相关性、卡方、巴氏距离等。通过示例代码展示了如何操作直方图并比较不同图像的直方图。
摘要由CSDN通过智能技术生成

图像直方图

图像直方图是图像的统计学特征

直方图的计算与显示

对图像进行统计,并且绘制他们各个灰度等级对应的直方图就可以的得到图像的直方图

计算直方图的api如下

calcHist(List images, MatOfInt channels, Mat mask, Mat hist, MatOfInt histSize, MatOfFloat ranges)

images:输入图像,类型必须相同

channels:通道索引列表

mask:遮罩层

hist:计算得到直方图数据,

histSize:直方图的大小

ranges:直方图的取值范围

实现代码如下

Mat m = Imgcodecs.imread("C:\\test\\ecy.jpg");

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

//灰度

Mat m1 = new Mat();

Imgproc.cvtColor(m,m1,Imgproc.COLOR_BGR2GRAY);

HighGui.imshow("灰度",m1);

//添加图像

List images = new ArrayList<>();

images.add(m1);

//计算直方图

Mat hist = new Mat();

Imgproc.calcHist(images,new MatOfInt(0),new Mat(),hist,new MatOfInt(256),new MatOfFloat(0,255));

//数值归一化

Core.normalize(hist,hist,0,255,Core.NORM_MINMAX);

int h = hist.rows();

Mat m2 = new Mat(new Size(300,300),m.type(),new Scalar(200,200,200));

float[] histdata = new float[256];

//获取数据

hist.get(0,0,histdata);

//绘制直方图

int x = 20;

int y = 280;//图像区域位置

Imgproc.line(m2,new Point(x,0),new Point(x,y),new Scalar(255,0,0));

Imgproc.line(m2,new Point(x,y),new Point(400,y),new Scalar(255,0,0));

for (int i = 0; i < h - 1; i++) {

int y1 = (int) histdata[i];

Rect rect = new Rect();

rect.x = x+i;

rect.y = y-y1;

rect.width= 1;

rect.height = y1;

Imgproc.rectangle(m2,rect.tl(),rect.br(),new Scalar(15,15,15));

}

HighGui.imshow("直方图",m2);

?i=20200205155630442.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly94aWFvc2h1YWkuYmxvZy5jc2RuLm5ldA==,size_16,color_FFFFFF,t_70

在此之后 我封装了一个Api函数

方便后面直接调用

/**

* @param name 显示直方图的窗口名

* @param gray 灰度图像

* @return 返回计算后的直方图 hist

*/

public static Mat showHist(String name,Mat...gray){

//添加图像

List images = new ArrayList<>(Arrays.asList(gray));

//计算直方图

Mat hist = new Mat();

Imgproc.calcHist(images,new MatOfInt(0),new Mat(),hist,new MatOfInt(256),new MatOfFloat(0,255));

//数值归一化

Core.normalize(hist,hist,0,255,Core.NORM_MINMAX);

int h = hist.rows();

//创建背景

Mat histImg = new Mat(new Size(300,300),CvType.CV_8UC3,new Scalar(200,200,200));

float[] histdata = new float[256];

//获取直方图数据

hist.get(0,0,histdata);

int x = 20;

int y = 280;

//绘制直方图

Imgproc.line(histImg,new Point(x,0),new Point(x,y),new Scalar(255,0,0));

Imgproc.line(histImg,new Point(x,y),new Point(400,y),new Scalar(255,0,0));

for (int i = 0; i < h - 1; i++) {

int y1 = (int) histdata[i];

Rect rect = new Rect();

rect.x = x+i;

rect.y = y-y1;

rect.width= 1;

rect.height = y1;

Imgproc.rectangle(histImg,rect.tl(),rect.br(),new Scalar(15,15,15));

}

HighGui.imshow(name,histImg);

return hist;

}

直方图均衡化

直方图均衡化的本质是改变图像的灰度分布,或者说改变图像直方图灰度分布,通过累计灰度级别与相关的数学变换公式,来改变原有的图像直方图灰度分布,然后用改变之后的灰度值重建图像,从而达到调整亮度和对比度的目的。

直方图均衡化Api如下

equalizeHist(Mat src, Mat dst)

src:输入 8位灰度图像

dst:输出 8位灰度图像

833aafaa7ff39d9bc74b47f42b07a579.png

实现代码如下

showHist 函数是上面整合出来的

Mat m = Imgcodecs.imread("C:\\test\\ecy.jpg");

//灰度

Mat m1 = new Mat();

Imgproc.cvtColor(m,m1,Imgproc.COLOR_BGR2GRAY);

HighGui.imshow("原图灰度",m1);

showHist("原图直方图",m1);

Mat m2 = new Mat();

Imgproc.equalizeHist(m1,m2);//均衡化

HighGui.imshow("均衡化后灰度",m2);

showHist("均衡化后直方图",m2);

直方图比较

直方图的比较可以叫做计算直方图的距离

下面是比较的Api

public static double compareHist(Mat H1, Mat H2, int method){}

H1:第一个输入直方图的数据

H2:第二个输出直方图的数据

method:方法

@return 返回比较结果

直方图的比较方法有下面几种

HISTCMP_CORREL = 0 相关性

HISTCMP_CHISQR = 1 卡方

HISTCMP_INTERSECT = 2 相交

HISTCMP_BHATTACHARYYA = 3 巴氏距离

HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA 海灵格距离(和巴氏一样)

HISTCMP_CHISQR_ALT = 4 可选卡方

HISTCMP_KL_DIV = 5 K-L散度

下面通过代码演示

结果图示和上一个一样

Mat m = Imgcodecs.imread("C:\\test\\ecy.jpg");

//灰度

Mat m1 = new Mat();

Imgproc.cvtColor(m,m1,Imgproc.COLOR_BGR2GRAY);

HighGui.imshow("原图灰度",m1);

Mat hist1 = showHist("原图直方图",m1);

Mat m2 = new Mat();

Imgproc.equalizeHist(m1,m2);

HighGui.imshow("均衡化后灰度",m2);

Mat hist2 = showHist("均衡化后直方图",m2);

//开始计算距离

double d;

d = Imgproc.compareHist(hist1,hist2,Imgproc.HISTCMP_CORREL);

System.out.println("相关性:"+d);

d = Imgproc.compareHist(hist1,hist2,Imgproc.HISTCMP_CHISQR);

System.out.println("卡方:"+d);

d = Imgproc.compareHist(hist1,hist2,Imgproc.HISTCMP_INTERSECT);

System.out.println("巴氏距离:"+d);

d = Imgproc.compareHist(hist1,hist2,Imgproc.HISTCMP_HELLINGER);

System.out.println("海灵格距离:"+d);

d = Imgproc.compareHist(hist1,hist2,Imgproc.HISTCMP_CHISQR_ALT);

System.out.println("可选卡方:"+d);

d = Imgproc.compareHist(hist1,hist2,Imgproc.HISTCMP_KL_DIV);

System.out.println("K-L散度:"+d);

输出结果

相关性:0.01892496480027808

卡方:171801.74023263433

巴氏距离:9967.928175032139

海灵格距离:0.4559564084806153

可选卡方:14483.22276347663

K-L散度:120281.57980569218

85b51b0e49575630dd8ad263e6a9a487.png

3bc44d77a31db6bd90f99fb0d76bd55d.png

Timeless小帅

发布了40 篇原创文章 · 获赞 38 · 访问量 2万+

私信

关注

标签:Imgproc,java,Mat,hist,OpenCV,直方图,灰度,new

来源: https://blog.csdn.net/qq_18604209/article/details/104171534

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值