时间:2021-05-19
本文为大家分享了JavaSE图像验证码简单识别程序,供大家参考,具体内容如下
首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色。
然后你就可以使用该类,对目标文件进行分析。具体怎么实现我觉得这个类非常清楚,就是将样本从左都有这么横向移动,匹配出一个合适的就将坐标调整到下个位置。
此程序已是3年多前写的,后来没有在深入写下去,图像识别一个很深的领域,得需要很深的数学功底跟思维能力,这个java的程序效率不高,也不能识别变形的或者拉伸的图片,但在那个年代,已经足够用了,大家如果有更好的开源的图像识别代码,请务必来信交流:)
/** * 图片解析引擎,适合做网站验证码的分析。 * 首先必须载入样品,解析器将从左到右横向扫描,发现于样本的就自动记录。 * 当然本程序不适合样本不是唯一的,也就是说要识别的图片被缩放或者坐标变动和变形本程序无法进行这样的识别。 * 如果图片中的颜色变化非常大,此程序可能会有问题,当然了你可以选择一个标准的值做为转换成0,1矩阵的标准。 * * 样本的制作:请将样本转换成灰度模式,只含有两色最好,当然了不转换我也帮你转换了。 * */import java.awt.Image;import java.awt.image.BufferedImage;import java.io.File;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import javax.imageio.ImageIO;public class ImageParser { // ------------------------------------------------------------ Private Data // 样本的矩阵 private static List swatches = null; // 样本的值 private static List swatcheValues = null; // 图片文件的矩阵化 private byte[][] targetColors; // ------------------------------------------------------------ Test main method public static void main(String[] args) { // 加入样本与其样本对应的数值 String[] files = new String[10]; String[] values = new String[10]; for (int i = 0; i < files.length; i++){ files[i] = "D:/workspace/SZXClientAPP/res/" + i + ".jpg"; values[i] = String.valueOf(i); } ImageParser parse = new ImageParser(files, values); long startime = System.currentTimeMillis(); try { // 解析图片 System.out.println(parse.parseValue("D:/workspace/SZXClientAPP/res/ValidateNum")); long sincetime = System.currentTimeMillis(); System.out.println("所花时间 = " + (sincetime - startime)); } catch (Exception e) { e.printStackTrace(); } } // ------------------------------------------------------------ Constructors /** * 载入所有样本路径与其样本对应的数值 * * @param files */ public ImageParser(String[] files, String[] values) { // 只允许样本创建一次即可 if (swatches == null && swatcheValues == null) { int fileslength = files.length; int valueslength = values.length; if(fileslength != valueslength){ System.out.println("样本文件与样本数值不匹配!请重新设置!"); return; } swatches = new ArrayList(fileslength); swatcheValues = new ArrayList(valueslength); int i = 0; try { for (; i < files.length; i++) { swatches.add(imageToMatrix(files[i])); swatcheValues.add(i, values[i]); } } catch (Exception e) { System.out.println(files[i] + " can not be parsed"); e.printStackTrace(); } } } public ImageParser() { super(); if (swatches == null || swatcheValues == null) { System.out.println("您未载入样本,请先载入样本!"); } } /** * 解析图片的值 * * @param parseFilePath * 给出图片路径 * @return 返回字符串 * @throws Exception */ public String parseValue(String parseFilePath) throws Exception { StringBuffer result = new StringBuffer(); targetColors = imageToMatrix(parseFilePath); // printMatrix(targetColors); int height = targetColors.length; int targetWidth = targetColors[0].length; int width = 0; Iterator it = swatches.iterator(); while (it.hasNext()) { byte[][] bytes = (byte[][]) it.next(); int templen = bytes[0].length; if (templen > width) width = templen; } // System.out.println("MaxWidth = " + width); // System.out.println("MaxHeight = " + height); int xTag = 0; while ((xTag + width) < targetWidth) { cout: { Iterator itx = swatches.iterator(); int i = 0; while (itx.hasNext()) { byte[][] bytes = (byte[][]) itx.next(); byte[][] temp = splitMatrix(targetColors, xTag, 0, width, height); // System.out.println(i++); if (isMatrixInBigMatrix(bytes, temp)) { xTag += width; // System.out.println("new maxtrix: "); // printMatrix(temp); result.append(swatcheValues.get(i)); break cout; } i++; } xTag++; } } return result.toString(); } // ------------------------------------------------------------ Private methods /** * 判断一个矩阵是否在另外的矩阵中 * * @param source * 源矩阵 * @param bigMatrix * 大的矩阵 * @return 如果存在就返回 true */ private static final boolean isMatrixInBigMatrix(byte[][] source, byte[][] bigMatrix) { if (source == bigMatrix) return true; if (source == null || bigMatrix == null) return false; if (source.length > bigMatrix.length) return false; try { for (int i = 0; i < source.length; i++) { if (source[i].length > bigMatrix[i].length) return false; } } catch (ArrayIndexOutOfBoundsException e) { return false; } int height = source.length; int width = source[0].length; int x = 0, y = 0; int i = 0, j = 0; int count = 0; int comparecount = height * width; for (; i < bigMatrix.length - height + 1; i++) { for (j = 0; j < bigMatrix[i].length - width + 1; j++) { cout: { x = 0; count = 0; for (int k = i; k < height + i; k++) { y = 0; for (int l = j; l < width + j; l++) { // System.out.println("bytes[" + x + "][" + y + "]" // + " = " + source[x][y] + ", " + "other[" // + k + "][" + l + "] = " + bigMatrix[k][l]); if ((source[x][y] & bigMatrix[k][l]) == source[x][y]) { count++; } else break cout; y++; } x++; } // System.out.println("count = " + count); if (count == comparecount) return true; } } } return false; } /** * 切割矩阵 * * @param source * 源矩阵 * @param x * X坐标 * @param y * Y坐标 * @param width * 矩阵的宽度 * @param height * 矩阵的高度 * @return 切割后的矩阵 */ private static final byte[][] splitMatrix(byte[][] source, int x, int y, int width, int height) { byte[][] resultbytes = new byte[height][width]; for (int i = y, k = 0; i < height + y; i++, k++) { for (int j = x, l = 0; j < width + x; j++, l++) { resultbytes[k][l] = source[i][j]; // System.out.println("source[" + i + "][" + j + "]" + " = " + // source[i][j] + ", " + "resultbytes[" // + k + "][" + l + "] = " + resultbytes[k][l]); } } return resultbytes; } /** * 图片转换成矩阵数组 * * @param filePath * 文件路径 * @return 返回矩阵 * @throws Exception * 可能会抛出异常 */ private byte[][] imageToMatrix(String filePath) throws Exception { // 读入文件 Image image = ImageIO.read(new File(filePath)); int w = image.getWidth(null); int h = image.getHeight(null); BufferedImage src = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); src.getGraphics().drawImage(image, 0, 0, null); byte[][] colors = new byte[h][w]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int rgb = src.getRGB(j, i); // 像素进行灰度处理 String sRed = Integer.toHexString(rgb).substring(2, 4); String sGreen = Integer.toHexString(rgb).substring(4, 6); String sBlank = Integer.toHexString(rgb).substring(6, 8); long ired = Math.round((Integer.parseInt(sRed, 16) * 0.3 + 0.5d)); long igreen = Math.round((Integer.parseInt(sGreen, 16) * 0.59 + 0.5d)); long iblank = Math.round((Integer.parseInt(sBlank, 16) * 0.11 + 0.5d)); long al = ired + igreen + iblank; // if (al > 127) // System.out.print(" " + " "); // else // System.out.print(" " + "1"); // System.out.print(" " + (tempint > = maxint ? 0 : 1)); // System.out.println("tempInt = " + tempint); // 此处的值可以将来修改成你所需要判断的值 colors[i][j] = (byte) (al > 127 ? 0 : 1); } // System.out.println(); } return colors; } /** * 打印矩阵 * * @param matrix */ private static final void printMatrix(byte[][] matrix) { for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { if (matrix[i][j] == 0) System.out.print(" "); else System.out.print(" 1"); } System.out.println(); } }}以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
1、介绍在爬虫中经常会遇到验证码识别的问题,现在的验证码大多分计算验证码、滑块验证码、识图验证码、语音验证码等四种。本文就是识图验证码,识别的是简单的验证码,要
0x00识别涉及技术验证码识别涉及很多方面的内容。入手难度大,但是入手后,可拓展性又非常广泛,可玩性极强,成就感也很足。验证码图像处理验证码图像识别技术主要是操
最近在折腾验证码识别。最终的脚本的识别率在92%左右,9000张验证码大概能识别出八千三四百张左右。好吧,其实是验证码太简单。下面就是要识别的验证码。我主要用的
上节我们了解了图形验证码的识别,简单的图形验证码我们可以直接利用Tesserocr来识别,但是近几年又出现了一些新型验证码,如滑动验证码,比较有代表性的就是极验
上节我们了解了图形验证码的识别,简单的图形验证码我们可以直接利用Tesserocr来识别,但是近几年又出现了一些新型验证码,如滑动验证码,比较有代表性的就是极验