博舍

Java 图像处理(一) java图像识别技术 pdf

Java 图像处理(一)

曾几何时,Java图像处理已经被认为是太过鸡肋,就连Java的创始公司,在java图像处理方面也是浅尝辄止,可能相比较C++,Java在这方面的处理,确实差强人意。

不过Java类库中有一个叫JAI的库,全程是javaadvancedimage—Java高级预想处理,其实个人觉得这个库非常丰富,奈何JAI只发行了2个版本就停止维护了,

到现在也没有找到源码,资料更是少的可怜。鉴于上述原因,本人将开始记录JAI以及Java二维图像相关知识,本文主要介绍Java图像的主要类以及图像基础知识。

Java中我们对图像的操纵一般使用BufferImage,比如我们一般会使用一下方法,将一个图片文件读取到bufferimage

BufferedImageimage=ImageIO.read(newFile("D:\Gis开发\数据\影像数据\tiff\china.tif"));

    这个是将已经存在的图片文件,读取到BufferedImage中,其实大家都知道图像之所以会呈现出各种颜色,无外乎就是像素值、颜色模型、样本模型这三个重要参数来体现的。其实Java的图像类

BufferedImage也无外乎这三个重要参数。比如我们通过BufferedImage构造参数就可以发现,其中一个构造参数是publicBufferedImage(ColorModelcm,WritableRasterraster,booleanisRasterPremultiplied,Hashtableproperties)

 这个构造参数中,ColorModel是颜色模型,raster是栅格数据,它是由像素值和样本模型构成的,这个我们可以通过它的构造函数看到

protectedWritableRaster(SampleModelsampleModel,DataBufferdataBuffer,Pointorigin)

其中sampleModel是样例模型,dataBuffer是像素值数组。

下面介绍以上三个要素:

ColorModel

Java中ColorModel的实现类主要有ComponentColorModel、IndexColorModel等,我们先来看看ComponentColorModel构造函数

publicComponentColorModel(ColorSpacecolorSpace,booleanhasAlpha,booleanisAlphaPremultiplied,inttransparency,inttransferType)

其中colorSpace很重要,颜色空间其实决定了最终这些像素值是如何呈现在我们硬件上的,比如我们的电脑显示器,印刷等。

比如常见以下颜色空间:

RGB彩色模型@NativepublicstaticfinalintTYPE_RGB=5;灰度模型@NativepublicstaticfinalintTYPE_GRAY=6CMYK彩色模型@NativepublicstaticfinalintTYPE_CMYK=9;

比如我们通常的彩色图是用 TYPE_RGB,创建灰度图用TYPE_GRAY,以及TYPE_CMYK颜色模型。

hasAlpha:是否有透明通道,比如常见的png(32),就有alpha通道  

isAlphaPremultiplied: 这是处理透明的一个参数(相对深奥,后面会详细研究)

transparency: 透明类型  其中1表示完全不透明 2表示完全透明或不透明 3表示介于两者之间,也就是透明度可调(一般选择3)

transferType:  就是像素的数据类型,跟下面的dataType我认为是一样的

SampleModelJava中sampleModel的实现类主要有ComponentSampleModel以及它的子类PixelInterleavedSampleModel,我们来看看它的构造函数publicComponentSampleModel(intdataType,intw,inth,intpixelStride,intscanlineStride,intbandOffsets[])

其中datatype:数据类型,即就是像素值的表示单位,比如常见的RGB三通道,使用TYPE_BYTE来表示,即就是每个通道8位,用0-255来表示,常见的DEM地形数据,也会直接使用TYPE_SHORT或者TYPE_FLOAT来定义。

w: 图片宽度 

h: 图片高度

pixelStride:像素步幅,其实就是我们的像素在宽和高方向的间隔设置,通常设置为1,表示每个像素都会填充一个值,如果设置为2,则表示每2个位置设置一个像素值,这样其中的databuffer数组就会相应的缩减。

scanlineStride: 线性步幅,如果pixelStride为1,则scanlineStride为width。

bandOffsets:波段偏移量,一般都是0,比如RGB数据,一般都是newint[]{0,0,0}

像素值

像素值其实就是表示颜色的数字,这里提示一点,比如RGB数据,如果数据类型是TYPE_BYTE,如果图片是10x10大小,则这个DataBufferByte的数组大小就是10*10*3。

下面我们来自定义一个图片:

byte[]rasterBuffer=newbyte[10*10*3];DataBufferBytedataBuffer=newDataBufferByte(rasterBuffer,10*10*3);ColorSpacespace=ColorSpace.getInstance(ColorSpace.CS_GRAY);ComponentSampleModelsampleModle=newComponentSampleModel(DataBuffer.TYPE_BYTE,10,10,1,10*3,newint[]{0,1,2});int[]bits={8,8,8};ComponentColorModelcolorModel=newComponentColorModel(space,bits,false,false,Transparency.TRANSLUCENT,DataBuffer.TYPE_BYTE);WritableRasterraster=Raster.createWritableRaster(sampleModle,dataBuffer,newPoint(0,0));BufferedImageimage=newBufferedImage(colorModel,raster,false,null);

 其实在日常开发中,我们经常会遇到ComponentColorModel,但是偶尔也会遇到IndexColorModel,这两个颜色模型有什么区别呢?

 自己找了一个这样的数据,解析后发现,如下操作

从这个输出可以看出,图像的是IndexColorModel和普通ComponentColorModel是一样的,唯一不同的是rgb的数组大小不一样,下面我们来看看对应的samplemodel

 可以看出虽然colorModel有3通道,但实际samplemodel的band只有一个,也就是说实际只有一个samplebands

这也就解是了原本按照三通道的样本,该数据的databuffer应该是7162*5968*3  而实际它的databuffer的size只有

7162*5968,也就是上图中的data的size大小,这跟我们平时看到的ComponentColorModel的data不一样,也就是用一位byte就表示了三个通道的颜色分量。

 扩展

 一般对于图像显示而言,我们拿到每个通道的颜色分量,其实还是需要转为显示器等输出设备可以识别的,这个我们可以通过ColorModel的getRGB()方法,我们来看下这个方法

publicintgetRGB(intpixel){if(numComponents>1){thrownewIllegalArgumentException("Morethanonecomponentperpixel");}if(signed){thrownewIllegalArgumentException("Componentvalueissigned");}

return(getAlpha(pixel)

Java OCR 图像智能字符识别技术,可识别中文

http://blog.csdn.net/zhoushuyan/article/details/5948289

验证码的OCR方式识别

http://ykf.iteye.com/blog/212431

 

几天一直在研究OCR技术,据我了解的情况,国内最专业的OCR软件只有2家,清华TH-OCR和汉王OCR,看了很多的OCR技术发现好多对英文与数字的支持都很好,可惜很多都不支持中文字符。Asprise-OCR,Tesseract3.0以前的版本,都不支持中文,其实我用了下Asprise-OCR算是速度比较的快了,可惜他鄙视中文,这个没有办法,正好这段时间知名的开源OCR引擎Tesseract3.0版本发布了,他给我们带来的好消息就是支持中文,相关的下载项目网站是:http://code.google.com/p/tesseract-ocr

虽然速度不是很客观可是毕竟人家开始支持中文也算是不错的,一个英文的语言包大概是1.8M,中文简体的语言包是39.5M,中文繁体的语言包是53M,这样就知道为什么识别中文慢的原因了

package com.ocr;

 

import java.awt.Graphics2D;

 

import java.awt.color.ColorSpace;

import java.awt.geom.AffineTransform;

import java.awt.image.AffineTransformOp;

import java.awt.image.BufferedImage;

import java.awt.image.ColorConvertOp;

import java.awt.image.ColorModel;

import java.awt.image.MemoryImageSource;

import java.awt.image.PixelGrabber;

 

 

/**

 *

 * 图像过滤,增强OCR识别成功率

 *

 */

public class ImageFilter{

    private BufferedImage image;

 

    private int iw, ih;

 

    private int[] pixels;

 

    public ImageFilter(BufferedImageimage){

       this.image =image;

       iw =image.getWidth();

       ih =image.getHeight();

       pixels = new int[iw * ih];

    }

 

    /** 图像二值化 */

    public BufferedImagechangeGrey(){

       PixelGrabberpg= new PixelGrabber(image.getSource(),0,0, iw, ih, pixels,0,iw);

       try {

           pg.grabPixels();

       } catch (InterruptedExceptione){

           e.printStackTrace();

       }

       // 设定二值化的域值,默认值为100

       int grey=100;

       // 对图像进行二值化处理,Alpha值保持不变

       ColorModelcm=ColorModel.getRGBdefault();

       for (int i=0;igrey){

              red=255;

           } else {

              red=0;

           }

 

           if (cm.getGreen(pixels[i])>grey){

              green=255;

           } else {

              green=0;

           }

 

           if (cm.getBlue(pixels[i])>grey){

              blue=255;

           } else {

              blue=0;

           }

 

           pixels[i]=alpha=green6){

                         green=green6;

                     } else {

                         green=green4;

                     }

                  }

              } else {

                  if (green4>green6){

                      green=green4;

                  } else {

                     if (green5>green6){

                         green=green6;

                     } else {

                         green=green5;

                     }

                  }

              }

 

              // int blue2=cm.getBlue(pixels[(i-1)* iw +j]);

              int blue4=cm.getBlue(pixels[i* iw +j-1]);

              int blue5=cm.getBlue(pixels[i* iw +j]);

              int blue6=cm.getBlue(pixels[i* iw +j+1]);

              // int blue8=cm.getBlue(pixels[(i+1)* iw +j]);

 

              // 水平方向进行中值滤波

              if (blue4>=blue5){

                  if (blue5>=blue6){

                     blue=blue5;

                  } else {

                     if (blue4>=blue6){

                         blue=blue6;

                     } else {

                         blue=blue4;

                     }

                  }

              } else {

                  if (blue4>blue6){

                     blue=blue4;

                  } else {

                     if (blue5>blue6){

                         blue=blue6;

                     } else {

                         blue=blue5;

                     }

                  }

              }

              pixels[i* iw +j]=alpha

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇

下一篇