本文為大家分享了JavaSE圖像驗證碼簡單識別程序,供大家參考,具體內容如下
首先你應該對圖片進行樣本采集,然后將樣本進行灰度處理,也就是變成黑白兩色。
然后你就可以使用該類,對目標文件進行分析。具體怎么實現我覺得這個類非常清楚,就是將樣本從左都有這么橫向移動,匹配出一個合適的就將坐標調整到下個位置。
此程序已是3年多前寫的,后來沒有在深入寫下去,圖像識別一個很深的領域,得需要很深的數學功底跟思維能力,這個java的程序效率不高,也不能識別變形的或者拉伸的圖片,但在那個年代,已經足夠用了,大家如果有更好的開源的圖像識別代碼,請務必來信交流:)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
/** * 圖片解析引擎,適合做網站驗證碼的分析。 * 首先必須載入樣品,解析器將從左到右橫向掃描,發現于樣本的就自動記錄。 * 當然本程序不適合樣本不是唯一的,也就是說要識別的圖片被縮放或者坐標變動和變形本程序無法進行這樣的識別。 * 如果圖片中的顏色變化非常大,此程序可能會有問題,當然了你可以選擇一個標準的值做為轉換成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); /* 將圖像轉換成0,1 */ // 此處的值可以將來修改成你所需要判斷的值 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(); } } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/O_Ochongchong/article/details/17715145