摘要
图像识别是目前很热门的研究领域,涉及的知识很广,包括信息论、模式识别、模糊数学、图像编码、内容分类等等。本文仅对使用Java实现了一个简单的图像文本二值处理,关于识别并未实现。步骤
-
建立文本字符模板二值矩阵
-
对测试字符进行二值矩阵化处理
代码
/*
* @(#)StdModelRepository.java
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.recognition.util;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
* Hold character charImgs as standard model repository.
* @author 88250
* @version 1.0.0.0, Mar 20, 2008
*/
public class StdModelRepository {
/**
* hold character images
*/
List<BufferedImage> charImgs = new ArrayList<BufferedImage>();
/**
* default width of a character
*/
static int width = 16;
/**
* default height of a character
*/
static int height = 28;
/**
* standard character model matrix
*/
public int[][][] stdCharMatrix = new int[27][width][height];
/**
* Default constructor.
*/
public StdModelRepository() {
BufferedImage lowercase = null;
try {
lowercase = ImageIO.read(new File("lowercase.png"));
} catch (IOException ex) {
Logger.getLogger(StdModelRepository.class.getName()).
log(Level.SEVERE, null, ex);
}
for (int i = 0; i < 26; i++) {
charImgs.add(lowercase.getSubimage(i * width,
0,
width,
height));
}
for (int i = 0; i < charImgs.size(); i++) {
Image image = charImgs.get(i);
int[] pixels = ImageUtils.getPixels(image,
image.getWidth(null),
image.getHeight(null));
stdCharMatrix[i] = ImageUtils.getSymbolMatrix(pixels, 0).clone();
ImageUtils.displayMatrix(stdCharMatrix[i]);
}
}
}
* @(#)StdModelRepository.java
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.recognition.util;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
* Hold character charImgs as standard model repository.
* @author 88250
* @version 1.0.0.0, Mar 20, 2008
*/
public class StdModelRepository {
/**
* hold character images
*/
List<BufferedImage> charImgs = new ArrayList<BufferedImage>();
/**
* default width of a character
*/
static int width = 16;
/**
* default height of a character
*/
static int height = 28;
/**
* standard character model matrix
*/
public int[][][] stdCharMatrix = new int[27][width][height];
/**
* Default constructor.
*/
public StdModelRepository() {
BufferedImage lowercase = null;
try {
lowercase = ImageIO.read(new File("lowercase.png"));
} catch (IOException ex) {
Logger.getLogger(StdModelRepository.class.getName()).
log(Level.SEVERE, null, ex);
}
for (int i = 0; i < 26; i++) {
charImgs.add(lowercase.getSubimage(i * width,
0,
width,
height));
}
for (int i = 0; i < charImgs.size(); i++) {
Image image = charImgs.get(i);
int[] pixels = ImageUtils.getPixels(image,
image.getWidth(null),
image.getHeight(null));
stdCharMatrix[i] = ImageUtils.getSymbolMatrix(pixels, 0).clone();
ImageUtils.displayMatrix(stdCharMatrix[i]);
}
}
}
/*
* @(#)ImageUtils.java
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.recognition.util;
import java.awt.Image;
import java.awt.image.PixelGrabber;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Mainipulation of image data.
* @author 88250
* @version 1.0.0.3, Mar 20, 2008
*/
public class ImageUtils {
/**
* Return all of the pixel values of sepecified <code>image</code>.
* @param image the sepecified image
* @param width width of the <code>image</code>
* @param height height of the <code>image</code>
* @return
*/
public static int[] getPixels(Image image, int width, int height) {
int[] pixels = new int[width * height];
try {
new PixelGrabber(image, 0, 0, width, height, pixels, 0, width).grabPixels();
} catch (InterruptedException ex) {
Logger.getLogger(ImageUtils.class.getName()).
log(Level.SEVERE, null, ex);
}
return pixels;
}
/**
* Get a matrix that described the <code>pixels</code>.
* <p>
* For example, the result of the matrix like this:
* <center>
* 0000000000000000<br>
* 0000000000000000<br>
* 0001111111110000<br>
* 0011111111111000<br>
* 0011111111111100<br>
* 0011000000011100<br>
* 0000000000011100<br>
* 0000111111111100<br>
* 0011111111111100<br>
* 0011111110011100<br>
* 0111100000011100<br>
* 0111100000011100<br>
* 0111100000111100<br>
* 0111100001111110<br>
* 0011111111111100<br>
* 0011111111111100<br>
* 0001111111111100<br>
* 0000000000000000<br>
* 0000000000000000<br>
* </center>
* it describes the alphbet 'a'.
* </p>
* @param pixels the pixel array
* @param sparseFactor sparse factor
* @return a matrix that describes a alphbet
*/
public static int[][] getSymbolMatrix(int[] pixels, int sparseFactor) {
final int width = StdModelRepository.width;
final int height = StdModelRepository.height;
int[][] ret = new int[width][height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (pixels[i * width + j] == -1) {
ret[j][i] = 0;
} else {
ret[j][i] = 1;
}
}
}
return ret;
}
/**
* Print the <code>matrix</code> under console.
* @param matrix the sepecified matrix data
*/
public static void displayMatrix(int[][] matrix) {
System.out.println(" ");
for (int i = 0; i < matrix[0].length; i++) {
for (int j = 0; j < matrix.length; j++) {
if (matrix[j][i] != 0) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
* @(#)ImageUtils.java
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.recognition.util;
import java.awt.Image;
import java.awt.image.PixelGrabber;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Mainipulation of image data.
* @author 88250
* @version 1.0.0.3, Mar 20, 2008
*/
public class ImageUtils {
/**
* Return all of the pixel values of sepecified <code>image</code>.
* @param image the sepecified image
* @param width width of the <code>image</code>
* @param height height of the <code>image</code>
* @return
*/
public static int[] getPixels(Image image, int width, int height) {
int[] pixels = new int[width * height];
try {
new PixelGrabber(image, 0, 0, width, height, pixels, 0, width).grabPixels();
} catch (InterruptedException ex) {
Logger.getLogger(ImageUtils.class.getName()).
log(Level.SEVERE, null, ex);
}
return pixels;
}
/**
* Get a matrix that described the <code>pixels</code>.
* <p>
* For example, the result of the matrix like this:
* <center>
* 0000000000000000<br>
* 0000000000000000<br>
* 0001111111110000<br>
* 0011111111111000<br>
* 0011111111111100<br>
* 0011000000011100<br>
* 0000000000011100<br>
* 0000111111111100<br>
* 0011111111111100<br>
* 0011111110011100<br>
* 0111100000011100<br>
* 0111100000011100<br>
* 0111100000111100<br>
* 0111100001111110<br>
* 0011111111111100<br>
* 0011111111111100<br>
* 0001111111111100<br>
* 0000000000000000<br>
* 0000000000000000<br>
* </center>
* it describes the alphbet 'a'.
* </p>
* @param pixels the pixel array
* @param sparseFactor sparse factor
* @return a matrix that describes a alphbet
*/
public static int[][] getSymbolMatrix(int[] pixels, int sparseFactor) {
final int width = StdModelRepository.width;
final int height = StdModelRepository.height;
int[][] ret = new int[width][height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (pixels[i * width + j] == -1) {
ret[j][i] = 0;
} else {
ret[j][i] = 1;
}
}
}
return ret;
}
/**
* Print the <code>matrix</code> under console.
* @param matrix the sepecified matrix data
*/
public static void displayMatrix(int[][] matrix) {
System.out.println(" ");
for (int i = 0; i < matrix[0].length; i++) {
for (int j = 0; j < matrix.length; j++) {
if (matrix[j][i] != 0) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
/*
* @(#)ImageTextRecognitor.java
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.recognition;
import cn.edu.ynu.sei.recognition.util.StdModelRepository;
import cn.edu.ynu.sei.recognition.util.ImageUtils;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
* Demonstrate recognition characters from a image.
* @author 88250
* @version 1.0.0.2, Mar 20, 2008
*/
public class ImageTextRecognitor {
private final static long serialVersionUID = 1L;
private StdModelRepository smr = new StdModelRepository();
private BufferedImage bufferedImage;
/**
* Default constructor.
*/
public ImageTextRecognitor() {
try {
bufferedImage = ImageIO.read(new File("a_yahei12.png"));
} catch (IOException ex) {
Logger.getLogger(StdModelRepository.class.getName()).
log(Level.SEVERE, null, ex);
}
}
/**
* Return the matched character with sepecified image.
* @param symbolMatrix the matrix of sepecified image
* @return the character
*/
// TODO: the core algorithm
public char getMatchResult(int[][] symbolMatrix) {
char result = 0;
int tmpEvaluation = 100;
int evaluation = 0;
return result;
}
/**
* Main program entry.
* @param args should be <code>null</code>
*/
public static void main(String[] args) {
ImageTextRecognitor irt = new ImageTextRecognitor();
BufferedImage bi = irt.bufferedImage;
Image img = bi.getScaledInstance(16, 28, BufferedImage.SCALE_FAST);
int[] testImgPixels = ImageUtils.getPixels(img, img.getWidth(null),
img.getHeight(null));
ImageUtils.displayMatrix(ImageUtils.getSymbolMatrix(testImgPixels, 2));
// irt.getMatchResult(ImageUtils.getPixels(bi,
// bi.getWidth(),
// bi.getHeight()));
}
}
* @(#)ImageTextRecognitor.java
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.recognition;
import cn.edu.ynu.sei.recognition.util.StdModelRepository;
import cn.edu.ynu.sei.recognition.util.ImageUtils;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
* Demonstrate recognition characters from a image.
* @author 88250
* @version 1.0.0.2, Mar 20, 2008
*/
public class ImageTextRecognitor {
private final static long serialVersionUID = 1L;
private StdModelRepository smr = new StdModelRepository();
private BufferedImage bufferedImage;
/**
* Default constructor.
*/
public ImageTextRecognitor() {
try {
bufferedImage = ImageIO.read(new File("a_yahei12.png"));
} catch (IOException ex) {
Logger.getLogger(StdModelRepository.class.getName()).
log(Level.SEVERE, null, ex);
}
}
/**
* Return the matched character with sepecified image.
* @param symbolMatrix the matrix of sepecified image
* @return the character
*/
// TODO: the core algorithm
public char getMatchResult(int[][] symbolMatrix) {
char result = 0;
int tmpEvaluation = 100;
int evaluation = 0;
return result;
}
/**
* Main program entry.
* @param args should be <code>null</code>
*/
public static void main(String[] args) {
ImageTextRecognitor irt = new ImageTextRecognitor();
BufferedImage bi = irt.bufferedImage;
Image img = bi.getScaledInstance(16, 28, BufferedImage.SCALE_FAST);
int[] testImgPixels = ImageUtils.getPixels(img, img.getWidth(null),
img.getHeight(null));
ImageUtils.displayMatrix(ImageUtils.getSymbolMatrix(testImgPixels, 2));
// irt.getMatchResult(ImageUtils.getPixels(bi,
// bi.getWidth(),
// bi.getHeight()));
}
}
测试
标准字符图像
测试字符图像
测试输出
init:deps-jar:
Compiling 2 source files to /home/daniel/Work/Sources/Java/ImageTextRecognition/build/classes
compile:
run:
*********
***********
************
** ***
***
**********
************
******* ***
**** ***
**** ***
**** ****
**** *****
************
************
***********
***
***
***
***
***
*** ******
************
************
***** *****
**** ****
**** ****
**** ***
*** ***
**** ***
**** ****
**** ****
***** *****
************
************
*** *******
*********
**********
***********
**** *
****
****
****
****
****
****
****
**** *
***********
**********
*********
***
***
***
***
***
**********
***********
************
**** ****
**** ****
**** ***
**** ***
**** ***
**** ***
**** ***
**** ****
**** ****
************
***********
**********
********
***********
************
**** ****
*** ****
**** ***
**************
**************
****
****
****
**** **
*************
************
**********
********
*********
*****
****
***
*************
*************
***
***
***
***
***
***
***
***
***
***
***
***
***
**********
***********
************
**** ****
**** ****
**** ***
**** ***
**** ***
**** ***
**** ***
**** ****
**** ****
************
***********
**********
***
****
* ****
**** *****
**********
*********
***
***
***
***
***
*** *******
***********
************
***** ****
**** ***
**** ***
**** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
***
***
***
***
*******
*******
***
***
***
***
***
***
***
***
***
***
***
*************
*************
****
****
****
****
********
********
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****
****
********
********
*******
***
***
***
***
***
*** ****
*** ****
*** ****
*** *****
********
*******
********
********
**** ****
*** *****
*** ****
*** ****
*** *****
*** *****
*** ****
*******
*******
***
***
***
***
***
***
***
***
***
***
***
***
***
***
***
********
********
*******
*************
**************
**************
*** **** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *** ***
*** *******
***********
************
***** ****
**** ***
**** ***
**** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
********
**********
************
**** ****
*** ****
**** ****
**** ****
**** ****
**** ****
**** ****
*** ****
**** ****
************
**********
********
*** ******
***********
************
***** *****
**** ****
**** ****
*** ***
*** ***
*** ***
**** ****
**** ****
***** *****
************
************
*** ******
***
***
***
***
***
***
**********
***********
************
**** ****
*** ****
**** ***
**** ***
**** ***
**** ***
**** ***
*** ****
**** ****
************
***********
**********
***
***
***
***
***
***
***********
***********
***********
****** *
*****
****
****
****
****
****
****
****
****
****
****
* *********
* **********
* **********
* **** *
****
*****
*********
*********
********
****
***
** ****
************
***********
**********
****
****
****
****
*************
*************
****
****
****
****
****
****
****
****
****
****
*****
********
*******
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
**** ***
**** ****
**** ****
***********
***********
**********
**** ***
**** ****
*** ****
**** ***
**** ****
*** ****
**** ***
**** ****
*** ****
**** ***
********
*******
******
******
****
*** **
*** **
*** **
**** **
**** **** ***
*** **** ***
*** **** ***
**** ***** ***
**************
*************
****** *****
***** *****
***** *****
**** *****
**** ***
****** ****
* **** ****
* **** *****
* ***** ****
* ********
* ******
*****
****
******
********
*********
**** ****
**** ****
***** ****
**** ****
**** ***
**** ****
*** ****
**** ****
**** ****
**** ****
**** ***
*** ****
**** ****
**** ***
*******
*******
******
*****
* ****
****
****
****
*****
******
******
* ***********
***********
****
*****
*****
****
****
****
*****
*****
****
****
****
************
************
*******
*******
********
* ***
* ***
*******
********
********
***** **
*** ***
*** ***
*********
********
********
BUILD SUCCESSFUL (total time: 1 second)