java 爬中 验证码识别_JAVA爬虫---验证码识别技术(一)
Python中有專門的圖像處理技術(shù)比如說(shuō)PIL,可以對(duì)驗(yàn)證碼一類的圖片進(jìn)行二值化處理,然后對(duì)圖片進(jìn)行分割,進(jìn)行像素點(diǎn)比較得到圖片中的數(shù)字。這種方案對(duì)驗(yàn)證碼的處理相對(duì)較少,運(yùn)用相對(duì)普遍,很多驗(yàn)證碼圖片可以通過(guò)這個(gè)方式得到識(shí)別,當(dāng)然還需要一部分的降噪處理。
什么是圖片二值化處理:簡(jiǎn)單也就是把一張五顏六色的驗(yàn)證碼處理成一張只由黑白構(gòu)成的驗(yàn)證碼,這個(gè)是為了方便后期我們和保存的黑白單一數(shù)字、字母進(jìn)行像素點(diǎn)比較。
什么是降噪處理:簡(jiǎn)單的解釋就是把驗(yàn)證碼中的干擾去掉一部分,降噪不可能完全降,但是可以處理一大部分就是對(duì)識(shí)別的一種進(jìn)步,畢竟如果降噪處理不行,對(duì)后期的像素點(diǎn)比較和結(jié)果值影響比較大。
今天我們用圖片的RGB的色彩比對(duì)技術(shù),用JAVA對(duì)圖片進(jìn)行一次二值化處理,然后識(shí)別。
原圖片:
二值化后圖片:
我們針對(duì)這個(gè)網(wǎng)頁(yè)的驗(yàn)證碼需要在自己庫(kù)中保存的模板類型:
.....這一類是用于后期像素點(diǎn)比較得到圖片本身數(shù)值的準(zhǔn)備。
那么基本流程我們知道了,我們就開始
第一步:圖片下載:
網(wǎng)頁(yè)的抓取有時(shí)候會(huì)有驗(yàn)證碼的識(shí)別,這樣我們就需要對(duì)http請(qǐng)求的包進(jìn)行解析,有的驗(yàn)證碼可以在js中解析得到,有的是直接返回該網(wǎng)頁(yè)頁(yè)面,反正可以找到這個(gè)img圖片進(jìn)行下載到本地就行,此處不一一贅述。
第二部:對(duì)下載到本地的圖片進(jìn)行二值化處理:
在這里我自己寫了一個(gè)腳本,供大家使用和參考:
public class MyImgDel {
//todo splitNums可以根據(jù)你給到的圖片色差進(jìn)行調(diào)整,在你自己使用時(shí),可以針對(duì)splitNums做一個(gè)循環(huán),每次加多少,得到不同的色差比的二值化后的圖片,因?yàn)椴煌膱D片可能干擾線、干擾點(diǎn)顏色原因,二值化后會(huì)有差異
//todo splitWidthNum:把圖片根據(jù)長(zhǎng)度切分的分?jǐn)?shù),這個(gè)可以根據(jù)你圖片中的數(shù)字個(gè)數(shù)進(jìn)行切分
public static final int splitNums=4000000;
public static final int splitWidthNum=5;
public static void main(String[] args) {
String path="F://test1.png";
try{
BufferedImage img=removeBackgroud(path);
ImageIO.write(img, "PNG", new File("F://test1-1.png"));
}catch (Exception e){
e.printStackTrace();
}
}
public static BufferedImage removeBackgroud(String picFile)
throws Exception {
BufferedImage img = ImageIO.read(new File(picFile));
img = img.getSubimage(1, 1, img.getWidth()-2, img.getHeight()-2);
int width = img.getWidth();
int height = img.getHeight();
double subWidth = (double) width/(splitWidthNum+0.0);
Map map = new HashMap();
for (int i = 0; i < splitWidthNum; i++) {
//todo 以下是對(duì)圖片進(jìn)行二值化處理,在這里我的思路是規(guī)定,色差范圍在splitNums到負(fù)splitNums之間的,算是同色,放入同一個(gè)色值,放入一個(gè)map中,map中的Key放色值,value放這個(gè)色值得個(gè)數(shù),后期就根據(jù)這個(gè)色值來(lái)對(duì)驗(yàn)證碼進(jìn)行二值化
for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth && x < width - 1; ++x) {
for (int y = 0; y < height; ++y) {
if (isWhite(img.getRGB(x, y)) == 1){
continue;
}
Map map2 = new HashMap();
for (Integer color : map.keySet()) {
map2.put(color,map.get(color));
}
for (Integer color : map2.keySet()) {
System.out.println(Math.abs(color)-Math.abs(img.getRGB(x, y)));
if (Math.abs(color)-Math.abs(img.getRGB(x, y))-splitNums){
map.put(color, map.get(color) + 1);
}else{
map.put(img.getRGB(x, y), 1);
}
}
if (map.isEmpty()){
map.put(img.getRGB(x, y), 1);
}
}
}
System.out.println("==============================");
int max = 0;
int colorMax = 0;
for (Integer color : map.keySet()) {
if (max < map.get(color)) {
max = map.get(color);
colorMax = color;
}
}
for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth&& x < width - 1; ++x) {
for (int y = 0; y < height; ++y) {
int ress=Math.abs(img.getRGB(x, y))-Math.abs(colorMax);
if (ress-splitNums) {
img.setRGB(x, y, Color.WHITE.getRGB());
} else {
img.setRGB(x, y, Color.BLACK.getRGB());
}
}
}
}
return img;
}
//todo 判斷是否為白色的方法
public static int isWhite(int colorInt) {
Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue()>600) {
return 1;
}
return 0;
}
}
處理到這里我們就可以得到一個(gè)二值化后的圖片了。
然后我們就要開始對(duì)二值化后的圖進(jìn)行等分,然后和我們樣本庫(kù)中的圖片進(jìn)行一次像素比對(duì)。
總結(jié)
以上是生活随笔為你收集整理的java 爬中 验证码识别_JAVA爬虫---验证码识别技术(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java多图片上传json_Spring
- 下一篇: java derby连接_JAVA-De