上一章節已經搭建好了基礎架構,接下來就是圖像處理和識別的代碼了。api
WebElement element = SeleniumUtil.findElement(driver,szsbEnum); return new ByteArrayInputStream(((TakesScreenshot) element).getScreenshotAs(OutputType.BYTES));
直接貼圖片處理的代碼架構
public BufferedImage cleanLinesInImage(BufferedImage oriBufferedImage) throws IOException{ BufferedImage bufferedImage = oriBufferedImage; int h = bufferedImage.getHeight(); int w = bufferedImage.getWidth(); // 灰度化 int[][] gray = new int[w][h]; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { int argb = bufferedImage.getRGB(x, y); // 圖像加亮(調整亮度識別率很是高) int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30); int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30); int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30); if (r >= 255) { r = 255; } if (g >= 255) { g = 255; } if (b >= 255) { b = 255; } gray[x][y] = (int) Math .pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2) * 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2); } } // 二值化 int threshold = ostu(gray, w, h); BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { if (gray[x][y] > threshold) { gray[x][y] |= 0x00FFFF; } else { gray[x][y] &= 0xFF0000; } binaryBufferedImage.setRGB(x, y, gray[x][y]); } } File file = FileUtil.file(IdUtil.fastUUID()+".png"); ImageIO.write(binaryBufferedImage,"png",file); //這裏開始是利用opencv的api進行處理 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); Mat imread = Imgcodecs.imread(file.getAbsolutePath()); Mat target = new Mat(); // Core.bitwise_not(imread,target); Mat kelner = Imgproc.getStructuringElement(MORPH_RECT, new Size(3, 3), new Point(-1, -1)); //膨脹 Imgproc.dilate(imread,target,kelner); //腐蝕 Imgproc.erode(target,target,kelner); oriBufferedImage = mat2BufImg(target,".png"); file.delete(); return oriBufferedImage; }
順便放一下圖片處理過程每一個步驟的細節~~~~
原始驗證碼 :
灰度和二值化 :
膨脹 :
腐蝕 : spa
public String getAuthCodeByOpencv(WebDriver driver, SeleniumUtil.SzsbEnum szsbEnum){ String code = ""; //獲取網頁驗證碼圖片 try (InputStream inputStream = AuthCodeScreenShotUtil.getAuthCodeImageById(driver, szsbEnum)) { try { code = tesseract.doOCR(ImageCleanPlanOpencv.INSTANCE.clean(ImageIO.read(inputStream))); } catch (TesseractException e) { e.printStackTrace(); } } catch (IOException e) { logger.warn(e.getMessage()); } //當前驗證碼是數字類型 直接去除數字之外全部值 code = code.replaceAll("\\D", ""); return code; }
參考文章
https://blog.csdn.net/liziqin4/article/details/83085635
https://blog.csdn.net/hechaojie_com/article/details/82057411