哎,项目要实现JAVA的图像二值化。纠结呀,在我影像中java对图像处理并不怎么好用,但是没办法,成本要控制,只能拿出我们最大的法宝Google。没想到Google了一下,java集成的图像处理并没有我相像的那么难用,经过不断地尝试,项目也成功进入测试阶段,现将二值化方面信息拿出来和大家共享,也请大家指正。
一、首先说一下javax.imageio.ImageIO吧。
JDk版本
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)
ImageIO可以处理的图像类型。
System.out.println(Arrays.asList(ImageIO.getReaderFormatNames()));
输出:[jpg, BMP, bmp, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
看可以看到JDK1.6通过ImageIO可以加载以上类型的图片。
二、通过BufferedImage来处理图片。
BufferedImage bi=ImageIO.read(new File("D:/Test/binary/test.jpg"));//通过imageio将图像载入
int h=bi.getHeight();//获取图像的高
int w=bi.getWidth();//获取图像的宽
int rgb=bi.getRGB(0, 0);//获取指定坐标的ARGB的像素值
可以看出通过BufferedImage 就可以轻松的获取图像的尺寸。
int BufferedImage.getRGB(x,y).获取到的是ARGB,最前面多了一个透明度。将返回的int转为16进制后,0-1透明度,2-3是R,4-5是G,6-7是B。
三、具体二值化的算法。
1、首先获取每个像素点的灰度值。目前使用简单的(R+G+B)/3
2、然后选定一个阀值。
3、将一个像素点灰度值和它周围的8个灰度值相加再除以9,然后和阀值比较。大于阀值的则置为255,小于则是0
四、废话少说,具体代码如下。
package image.binary;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class BinaryTest {
public static void main(String[] args) throws IOException {
BufferedImage bi=ImageIO.read(new File("D:/Test/binary/test.jpg"));//通过imageio将图像载入
int h=bi.getHeight();//获取图像的高
int w=bi.getWidth();//获取图像的宽
int rgb=bi.getRGB(0, 0);//获取指定坐标的ARGB的像素值
int[][] gray=new int[w][h];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
gray[x][y]=getGray(bi.getRGB(x, y));
}
}
BufferedImage nbi=new BufferedImage(w,h,BufferedImage.TYPE_BYTE_BINARY);
int SW=160;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if(getAverageColor(gray, x, y, w, h)>SW){
int max=new Color(255,255,255).getRGB();
nbi.setRGB(x, y, max);
}else{
int min=new Color(0,0,0).getRGB();
nbi.setRGB(x, y, min);
}
}
}
ImageIO.write(nbi, "jpg", new File("D:/Test/binary/二值化后_无压缩.jpg"));
}
public static int getGray(int rgb){
String str=Integer.toHexString(rgb);
int r=Integer.parseInt(str.substring(2,4),16);
int g=Integer.parseInt(str.substring(4,6),16);
int b=Integer.parseInt(str.substring(6,8),16);
//or 直接new个color对象
Color c=new Color(rgb);
r=c.getRed();
g=c.getGreen();
b=c.getBlue();
int top=(r+g+b)/3;
return (int)(top);
}
/**
* 自己加周围8个灰度值再除以9,算出其相对灰度值
* @param gray
* @param x
* @param y
* @param w
* @param h
* @return
*/
public static int getAverageColor(int[][] gray, int x, int y, int w, int h)
{
int rs = gray[x][y]
+ (x == 0 ? 255 : gray[x - 1][y])
+ (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])
+ (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1])
+ (y == 0 ? 255 : gray[x][y - 1])
+ (y == h - 1 ? 255 : gray[x][y + 1])
+ (x == w - 1 ? 255 : gray[x + 1][ y])
+ (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])
+ (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);
return rs / 9;
}
}
相对较简单,将一个jpg图片二值化后产生一个无压缩的jpg文件。
五、压缩
有些时候是需要将二值化后的图片进行压缩的,然后转成tiff格式的文件,以减少存储成本。但是jdk1.6的imageIO还没有加入TIFF格式的图像处理,那么可以使用辅助的包了。
1、jai-imageio包。目前发布的最新版本为1.1,1.2还在开发中。。
http://download.java.net/media/jai-imageio/builds/release/1_0_01/jai_imageio-1_0_01-windows-i586-jar.zip
2、解压后就两个jar包和一个dll。dll丢进PATH中,jar包放入工程,则我们就可以做压缩咯。
System.out.println(Arrays.asList(ImageIO.getWriterFormatNames()));
看看,加入jar后的Imageio:
[raw, tif, jpeg, JFIF, WBMP, jpeg-lossless, jpeg-ls, PNM, JPG, wbmp, PNG, JPEG, jpeg 2000, tiff, BMP, JPEG2000, RAW, JPEG-LOSSLESS, jpeg2000, GIF, TIF, TIFF, bmp, jpg, pnm, png, jfif, JPEG 2000, gif, JPEG-LS]
是不是可以处理的格式更强大了呢。。
3、压缩的全部代码。。
package image.binary;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriterSpi;
public class BinaryTest {
public static void main(String[] args) throws IOException {
BufferedImage bi=ImageIO.read(new File("D:/Test/binary/test.jpg"));//通过imageio将图像载入
int h=bi.getHeight();//获取图像的高
int w=bi.getWidth();//获取图像的宽
int[][] gray=new int[w][h];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
gray[x][y]=getGray(bi.getRGB(x, y));
}
}
BufferedImage nbi=new BufferedImage(w,h,BufferedImage.TYPE_BYTE_BINARY);
int SW=160;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if(getAverageColor(gray, x, y, w, h)>SW){
int max=new Color(255,255,255).getRGB();
nbi.setRGB(x, y, max);
}else{
int min=new Color(0,0,0).getRGB();
nbi.setRGB(x, y, min);
}
}
}
TIFFImageWriterSpi tiffws=new TIFFImageWriterSpi();
ImageWriter writer=tiffws.createWriterInstance();
ImageWriteParam param=writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionType("CCITT T.6");
param.setCompressionQuality(0.8f);
File outFile=new File("D:/Test/binary/二值化后_有压缩.tiff");
ImageOutputStream ios=ImageIO.createImageOutputStream(outFile);
writer.setOutput(ios);
writer.write(null,new IIOImage(nbi, null, null), param);
}
public static int getGray(int rgb){
String str=Integer.toHexString(rgb);
int r=Integer.parseInt(str.substring(2,4),16);
int g=Integer.parseInt(str.substring(4,6),16);
int b=Integer.parseInt(str.substring(6,8),16);
//or 直接new个color对象
Color c=new Color(rgb);
r=c.getRed();
g=c.getGreen();
b=c.getBlue();
int top=(r+g+b)/3;
return (int)(top);
}
/**
* 自己加周围8个灰度值再除以9,算出其相对灰度值
* @param gray
* @param x
* @param y
* @param w
* @param h
* @return
*/
public static int getAverageColor(int[][] gray, int x, int y, int w, int h)
{
int rs = gray[x][y]
+ (x == 0 ? 255 : gray[x - 1][y])
+ (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])
+ (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1])
+ (y == 0 ? 255 : gray[x][y - 1])
+ (y == h - 1 ? 255 : gray[x][y + 1])
+ (x == w - 1 ? 255 : gray[x + 1][ y])
+ (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])
+ (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);
return rs / 9;
}
}
六、总结。。
1、效率问题还可以满足我们项目的要求,但是如果有同学想这样用的话一定要实际测试一下效率哦。
2、以及处理的图片效果。附件1.1版本的jai。
分享到:
相关推荐
本文将深入探讨如何在Java中实现图像二值化,并去除白边以实现紧包效果。 首先,我们需要理解二值化的原理。在灰度图像中,每个像素点的值介于0(黑色)到255(白色)之间。二值化就是设定一个阈值,小于阈值的像素...
本篇文章将深入探讨几个关键的图像处理技术,包括灰度化、二值化、降噪、图像切割、裁剪以及寻找相似图像的方法。 1. **灰度化**: 灰度化是将彩色图像转换为单色图像的过程,每个像素由一个强度值表示,范围通常...
在图像处理领域,二值化是一种非常基础且重要的技术,它将图像转化为只有两种颜色的简单形式,通常为黑色和...以上就是关于Java实现图片二值化的详细知识点,包括基本原理、代码实现以及优化策略。希望对您有所帮助!
在这个项目中,我们将深入探讨如何使用Java结合OpenCV库实现图像的灰度化、二值化、轮廓描边以及边缘检测等基本操作。这些功能在图像分析、识别和机器学习应用中扮演着重要角色。 首先,我们来看**灰度化**。灰度化...
在Android中,实现图片二值化的步骤如下: 1. **读取图片**:首先,我们需要使用`BitmapFactory`类的`decodeResource()`或`decodeStream()`方法从资源文件或流中加载图片,得到`Bitmap`对象。 2. **获取像素数据**...
在这个Java测试例子中,我们聚焦于如何使用Java实现图像的二值化处理,并进行图像相似度的比较。下面我们将深入探讨这个主题。 首先,我们要了解什么是二值化。在数字图像处理中,二值化是将图像上的像素点的灰度值...
一直以来对Java的图形处理能力表无力,但好像又不是那么一回事,之前用PHP做过一些应用,涉及到验证码的识别,其中有个图片二值化的步骤,今天换成Java来实现下 在java的扩展包javax.imageio中为我们提供了一个类...
对图像进行二值化、锐化、中值滤波、线性灰度变换、平滑缩放、转黑白图像等算法,用JAVA实现
总之,这个Android JNI图像处理库是一个高效且功能丰富的工具,可以帮助开发者快速实现图像二值化和其它处理功能。通过学习和使用这个库,开发者不仅可以提升应用程序的性能,还能深入理解JNI和图像处理的基本原理。
在给定的压缩包文件中,我们重点关注几个关键的图像处理技术:灰度化、二值化、降噪、图像切割、裁剪以及寻找相似图像。下面将详细解释这些概念及其在Java中的实现。 1. **灰度化**: 灰度化是将彩色图像转换为...
图像二值化是一种重要的图像处理技术,常用于将图像转换为黑白两色调,便于后续的图像分析、识别和处理。动态阈值确定算法是解决这一问题的关键,它能根据图像的局部特性或全局特性自动调整阈值,提高二值化效果。在...
在本文中,我们将深入探讨基于Java的数字图像处理技术,主要关注标题中提及的几个关键领域:二值化、灰度处理、RGB色彩通道过滤以及卷积滤镜。这些都是图像处理中的基本操作,广泛应用于图像分析、计算机视觉、机器...
7. **二值化图像**:最后,根据找到的最佳阈值,对图像进行二值化处理。所有灰度值小于阈值的像素设为前景色(如白色),大于或等于阈值的像素设为背景色(如黑色)。 在实际编程中,OTSU算法的实现可能会包含一些...
总结来说,这个项目通过Java实现了多种图像去噪算法,涵盖了光斑、雾、暗部以及水印的去除,对于提升图像质量有着显著效果。开发者可以通过学习和利用这个SDK,进一步提升他们的图像处理应用的功能和用户体验。
本项目着重讲解如何利用ImageJ的Java代码和OpenCV库在C++环境下实现16种不同的自动二值化算法,以达到对图像进行高效处理的目的。 首先,我们要理解ImageJ和OpenCV这两个库在图像处理中的作用。ImageJ是一款开源的...
为android提供的二值化jni库,和完整demo,比Java代码的效率高10s! 一个基于jni的图像处理工具 包括二值化 灰度化 膨胀 腐蚀 等等 是android上图像处理的好例子 还能提高处理速度!实现点阵图的转化
在Android平台上处理图片是开发过程中常见的任务之一,其中包括多种图像操作,如图像二值化、锐化以及转换格式。以下是对这些概念的详细说明: **图像二值化**: 图像二值化是一种将图像转化为黑白两色调的过程,常...
本主题将深入探讨如何使用基本组件来实现图像处理中的几个关键操作,包括二值化、反色、灰度化、锐化和色调调整。这些技术对于理解和创建自己的图像处理系统至关重要。 首先,我们来看**二值化**。这是一种将图像...
本文将详细介绍如何使用Java语言实现图像的灰度化和二值化处理,并通过具体的代码示例来解释其实现过程。 #### 二、灰度化 灰度化是指将彩色图像转换为灰度图像的过程。在这个过程中,每个像素的颜色由三个分量...