本文為大家分享了JavaSE圖像驗(yàn)證碼簡(jiǎn)單識(shí)別程序,供大家參考,具體內(nèi)容如下
首先你應(yīng)該對(duì)圖片進(jìn)行樣本采集,然后將樣本進(jìn)行灰度處理,也就是變成黑白兩色。
然后你就可以使用該類,對(duì)目標(biāo)文件進(jìn)行分析。具體怎么實(shí)現(xiàn)我覺得這個(gè)類非常清楚,就是將樣本從左都有這么橫向移動(dòng),匹配出一個(gè)合適的就將坐標(biāo)調(diào)整到下個(gè)位置。
此程序已是3年多前寫的,后來(lái)沒有在深入寫下去,圖像識(shí)別一個(gè)很深的領(lǐng)域,得需要很深的數(shù)學(xué)功底跟思維能力,這個(gè)java的程序效率不高,也不能識(shí)別變形的或者拉伸的圖片,但在那個(gè)年代,已經(jīng)足夠用了,大家如果有更好的開源的圖像識(shí)別代碼,請(qǐng)務(wù)必來(lái)信交流:)
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
|
/** * 圖片解析引擎,適合做網(wǎng)站驗(yàn)證碼的分析。 * 首先必須載入樣品,解析器將從左到右橫向掃描,發(fā)現(xiàn)于樣本的就自動(dòng)記錄。 * 當(dāng)然本程序不適合樣本不是唯一的,也就是說(shuō)要識(shí)別的圖片被縮放或者坐標(biāo)變動(dòng)和變形本程序無(wú)法進(jìn)行這樣的識(shí)別。 * 如果圖片中的顏色變化非常大,此程序可能會(huì)有問題,當(dāng)然了你可以選擇一個(gè)標(biāo)準(zhǔn)的值做為轉(zhuǎn)換成0,1矩陣的標(biāo)準(zhǔn)。 * * 樣本的制作:請(qǐng)將樣本轉(zhuǎn)換成灰度模式,只含有兩色最好,當(dāng)然了不轉(zhuǎn)換我也幫你轉(zhuǎn)換了。 * */ 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) { // 加入樣本與其樣本對(duì)應(yīng)的數(shù)值 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( "所花時(shí)間 = " + (sincetime - startime)); } catch (Exception e) { e.printStackTrace(); } } // ------------------------------------------------------------ Constructors /** * 載入所有樣本路徑與其樣本對(duì)應(yīng)的數(shù)值 * * @param files */ public ImageParser(String[] files, String[] values) { // 只允許樣本創(chuàng)建一次即可 if (swatches == null && swatcheValues == null ) { int fileslength = files.length; int valueslength = values.length; if (fileslength != valueslength){ System.out.println( "樣本文件與樣本數(shù)值不匹配!請(qǐng)重新設(shè)置!" ); 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( "您未載入樣本,請(qǐng)先載入樣本!" ); } } /** * 解析圖片的值 * * @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 /** * 判斷一個(gè)矩陣是否在另外的矩陣中 * * @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坐標(biāo) * @param y * Y坐標(biāo) * @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; } /** * 圖片轉(zhuǎn)換成矩陣數(shù)組 * * @param filePath * 文件路徑 * @return 返回矩陣 * @throws Exception * 可能會(huì)拋出異常 */ 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); // 像素進(jìn)行灰度處理 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); /* 將圖像轉(zhuǎn)換成0,1 */ // 此處的值可以將來(lái)修改成你所需要判斷的值 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(); } } } |
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://blog.csdn.net/O_Ochongchong/article/details/17715145