Java基于直方图应用的相似图片识别实例
本文实例讲述了Java实现基于直方图应用的相似图片识别,是非常实用的技巧。分享给大家供大家参考。具体分析如下:
一、算法概述:
首先对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再使用巴氏系数算法对直方图数据进行计算,最终得出图像相似度值,其值范围在[0,1]之间
0表示极其不同,1表示极其相似(相同)。
二、算法步骤详解:
大致可以分为两步,根据源图像与候选图像的像素数据,生成各自直方图数据。第二步:使用第一步输出的直方图结果,运用巴氏系数(Bhattacharyyacoefficient)算法,计算出相似程度值。
第一步:直方图计算
直方图分为灰度直方图与RGB直方图,对于灰度图像直方图计算十分简单,只要初始化一个大小为256的直方图数组H,然后根据像素值完成频率分布统计,假设像素值为124,则H[124]+=1,而对于彩色RGB像素来说直方图表达有两种方式,一种是单一直方图,另外一种是三维直方图,三维直方图比较简单明了,分别对应RGB三种颜色,定义三个直方图HR,HG,HB,假设某一个像素点P的RGB值为(4,231,129),则对于的直方图计算为HR[4]+=1,HG[231]+=1,HB[129]+=1,如此对每个像素点完成统计以后,RGB彩色直方图数据就生成了。
而RGB像素的单一直方图SH表示稍微复杂点,每个颜色的值范围为0~255之间的,假设可以分为一定范围等份,当8等份时,每个等份的值范围为32,16等份时,每个等份值范围为16,当4等份时候,每个等份值的范围为64,假设RGB值为(14,68,221),16等份之后,它对应直方图索引值(index)分别为:(0,4,13),根据计算索引值公式:index=R+G*16+B*16*16
对应的直方图index=0+4*16+13*16*16,SH[3392]+=1
如此遍历所有RGB像素值,完成直方图数据计算。
第二步:巴氏系数计算,计算公式如下:
其中P,P"分别代表源与候选的图像直方图数据,对每个相同i的数据点乘积开平方以后相加
得出的结果即为图像相似度值(巴氏系数因子值),范围为0到1之间。
程序效果如下图所示:
相似度超过99%以上,极其相似
相似度为:72%,一般相似
三、程序直方图计算源代码如下:
publicvoidsetGreenBinCount(intgreenBinCount){ this.greenBins=greenBinCount; } publicvoidsetBlueBinCount(intblueBinCount){ this.blueBins=blueBinCount; } publicfloat[]filter(BufferedImagesrc,BufferedImagedest){ intwidth=src.getWidth(); intheight=src.getHeight(); int[]inPixels=newint[width*height]; float[]histogramData=newfloat[redBins*greenBins*blueBins]; getRGB(src,0,0,width,height,inPixels); intindex=0; intredIdx=0,greenIdx=0,blueIdx=0; intsingleIndex=0; floattotal=0; for(introw=0;row<height;row++){ intta=0,tr=0,tg=0,tb=0; for(intcol=0;col<width;col++){ index=row*width+col; ta=(inPixels[index]>>24)&0xff; tr=(inPixels[index]>>16)&0xff; tg=(inPixels[index]>>8)&0xff; tb=inPixels[index]&0xff; redIdx=(int)getBinIndex(redBins,tr,255); greenIdx=(int)getBinIndex(greenBins,tg,255); blueIdx=(int)getBinIndex(blueBins,tb,255); singleIndex=redIdx+greenIdx*redBins+blueIdx*redBins*greenBins; histogramData[singleIndex]+=1; total+=1; } } //starttonormalizethehistogramdata for(inti=0;i<histogramData.length;i++) { histogramData[i]=histogramData[i]/total; } returnhistogramData; }
计算巴氏系数的代码如下:
/** *BhattacharyyaCoefficient *http://www.cse.yorku.ca/~kosta/CompVis_Notes/bhattacharyya.pdf * *@return */ publicdoublemodelMatch(){ HistogramFilterhfilter=newHistogramFilter(); float[]sourceData=hfilter.filter(sourceImage,null); float[]candidateData=hfilter.filter(candidateImage,null); double[]mixedData=newdouble[sourceData.length]; for(inti=0;i<sourceData.length;i++){ mixedData[i]=Math.sqrt(sourceData[i]*candidateData[i]); } //ThevaluesofBhattacharyyaCoefficientrangesfrom0to1, doublesimilarity=0; for(inti=0;i<mixedData.length;i++){ similarity+=mixedData[i]; } //Thedegreeofsimilarity returnsimilarity; }
希望本文所述对大家的Java程序设计有所帮助。
相关文章
- java反转数组_Java实现数组反转翻转的方法实例
- java–Quartz 定时执行
- java parrallel for,Java 8 parallel forEach进度指示
- n皇后问题 回溯法java_Java解决N皇后问题
- java 反射getmethod_Java 反射机制中 getMethod()和getDeclaredField()区别
- JAVA静态内部类_java静态内部类实例化
- 阿里开发人员献礼“Java架构成长笔记”,深入内核,拒绝蒙圈
- 如何在 Java 8 中使用 Streams?结合多种案例剖析学习!
- Java 程序初始化过程详解 -转编程语言
- 解决Java程序连接MySQL的准确方案:Java连接MySQL的Jar包(java连接mysql的jar包)
- Java多线程4:synchronized锁机制详解编程语言
- Java编程操作Oracle数据库(java操作oracle)
- 时间优雅地设置Redis Java的过期时间(redisjava过期)
- 处理Java调用Redis处理过期Key的有效方法(redisjava过期)
- Linux下安装Java 开发环境指南(linux装java环境)
- Java调用Redis实现高性能数据存储(java调用redis)
- 机制实现redis中java代码过期机制策略(redisjava过期)
- 设置Java中Redis过期策略的实现(redisjava过期)
- 策略Java使用Redis实现过期策略(redisjava过期)
- 实现Java实现Redis锁的研究与应用(redis锁java)
- 在macOS上使用Java编程(macosjava)
- Java与MySQL共同构建良好的数据表(java mysql 表)
- Java程序员的MySQL数据库之旅(java操作mysql数据库)
- 利用JAVA实现DES加密算法
- java使用动态代理来实现AOP(日志记录)的实例代码