图片验证码--BufferedImage 图片验证码去除干扰线
java-BufferedImage 图片验证码去除干扰线的方法( 用于OCR tesseract图像智能字符识别)
图片验证码自动识别的功能
网上对于初始图片的处理方法有去噪点、灰度化等,唯独难搜到去除干扰线的方法,可以比较干净地去除干扰线,提高OCR识别的准确率,“去除干扰线条“.
测试样板图片和数据:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;import javax.imageio.ImageIO;public class CopyOfCleanLines {public static void main(String[] args) throws IOException { File testDataDir = File("F:\\ocr"); final String destDir = testDataDir.getAbsolutePath()+"/tmp"; for (File file : testDataDir.listFiles()) { cleanLinesInImage(file, destDir); cleanLinesInImage(file, destDir); cleanLinesInImage(file, destDir);} } /** * * @param sfile * 需要去噪的图像 * @param destDir * 去噪后的图像保存地址 * @throws IOException */ public static void cleanLinesInImage(File sfile, String destDir) throws IOException{ File destF = new File(destDir); if (!destF.exists()) { destF.mkdirs(); } BufferedImage bufferedImage = ImageIO.read(sfile); 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]); } } //去除干扰线条for(int y = 1; y < h-1; y++){for(int x = 1; x < w-1; x++){ boolean flag = false ;if(isBlack(binaryBufferedImage.getRGB(x, y))){//左右均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y)) && isWhite(binaryBufferedImage.getRGB(x+1, y))){flag = true;}//上下均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x, y+1)) && isWhite(binaryBufferedImage.getRGB(x, y-1))){flag = true;}//斜上下为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y+1)) && isWhite(binaryBufferedImage.getRGB(x+1, y-1))){flag = true;}if(isWhite(binaryBufferedImage.getRGB(x+1, y+1)) && isWhite(binaryBufferedImage.getRGB(x-1, y-1))){flag = true;} if(flag){binaryBufferedImage.setRGB(x,y,-1); }}}}// 矩阵打印 for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (isBlack(binaryBufferedImage.getRGB(x, y))) { System.out.print("*"); } else { System.out.print(" "); } } System.out.println(); } ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile .getName())); } public static boolean isBlack(int colorInt) { Color color = new Color(colorInt); if (color.getRed() + color.getGreen() + color.getBlue() <= 300) { return true; } return false; } public static boolean isWhite(int colorInt) { Color color = new Color(colorInt); if (color.getRed() + color.getGreen() + color.getBlue() > 300) { return true; } return false; } public static int isBlackOrWhite(int colorInt) { if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730) { return 1; } return 0; } public static int getColorBright(int colorInt) { Color color = new Color(colorInt); return color.getRed() + color.getGreen() + color.getBlue(); } public static int ostu(int[][] gray, int w, int h) { int[] histData = new int[w * h]; // Calculate histogram for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { int red = 0xFF & gray[x][y]; histData[red]++; } } // Total number of pixels int total = w * h; float sum = 0; for (int t = 0; t < 256; t++) sum += t * histData[t]; float sumB = 0; int wB = 0; int wF = 0; float varMax = 0; int threshold = 0; for (int t = 0; t < 256; t++) { wB += histData[t]; // Weight Background if (wB == 0) continue; wF = total - wB; // Weight Foreground if (wF == 0) break; sumB += (float) (t * histData[t]); float mB = sumB / wB; // Mean Background float mF = (sum - sumB) / wF; // Mean Foreground // Calculate Between Class Variance float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF); // Check if new maximum found if (varBetween > varMax) { varMax = varBetween; threshold = t; } } return threshold; }
}
package com.gazgeek.helloworld.controller;import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;import javax.imageio.ImageIO;public class CopyOfCleanLines {public static void main(String[] args) throws IOException{File testDataDir = new File("F:\\ocr");final String destDir = testDataDir.getAbsolutePath()+"/tmp";for (File file : testDataDir.listFiles()){cleanLinesInImage(file, destDir);cleanLinesInImage(file, destDir);cleanLinesInImage(file, destDir);}}/**** @param sfile* 需要去噪的图像* @param destDir* 去噪后的图像保存地址* @throws IOException*/public static void cleanLinesInImage(File sfile, String destDir) throws IOException{File destF = new File(destDir);if (!destF.exists()){destF.mkdirs();}BufferedImage bufferedImage = ImageIO.read(sfile);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]);}}//去除干扰线条for(int y = 1; y < h-1; y++){for(int x = 1; x < w-1; x++){boolean flag = false ;if(isBlack(binaryBufferedImage.getRGB(x, y))){//左右均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y)) && isWhite(binaryBufferedImage.getRGB(x+1, y))){flag = true;}//上下均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x, y+1)) && isWhite(binaryBufferedImage.getRGB(x, y-1))){flag = true;}//斜上下为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y+1)) && isWhite(binaryBufferedImage.getRGB(x+1, y-1))){flag = true;}if(isWhite(binaryBufferedImage.getRGB(x+1, y+1)) && isWhite(binaryBufferedImage.getRGB(x-1, y-1))){flag = true;}if(flag){binaryBufferedImage.setRGB(x,y,-1);}}}}// 矩阵打印for (int y = 0; y < h; y++){for (int x = 0; x < w; x++){if (isBlack(binaryBufferedImage.getRGB(x, y))){System.out.print("*");} else{System.out.print(" ");}}System.out.println();}ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile.getName()));}public static boolean isBlack(int colorInt){Color color = new Color(colorInt);if (color.getRed() + color.getGreen() + color.getBlue() <= 300){return true;}return false;}public static boolean isWhite(int colorInt){Color color = new Color(colorInt);if (color.getRed() + color.getGreen() + color.getBlue() > 300){return true;}return false;}public static int isBlackOrWhite(int colorInt){if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730){return 1;}return 0;}public static int getColorBright(int colorInt){Color color = new Color(colorInt);return color.getRed() + color.getGreen() + color.getBlue();}public static int ostu(int[][] gray, int w, int h){int[] histData = new int[w * h];// Calculate histogramfor (int x = 0; x < w; x++){for (int y = 0; y < h; y++){int red = 0xFF & gray[x][y];histData[red]++;}}// Total number of pixelsint total = w * h;float sum = 0;for (int t = 0; t < 256; t++)sum += t * histData[t];float sumB = 0;int wB = 0;int wF = 0;float varMax = 0;int threshold = 0;for (int t = 0; t < 256; t++){wB += histData[t]; // Weight Backgroundif (wB == 0)continue;wF = total - wB; // Weight Foregroundif (wF == 0)break;sumB += (float) (t * histData[t]);float mB = sumB / wB; // Mean Backgroundfloat mF = (sum - sumB) / wF; // Mean Foreground// Calculate Between Class Variancefloat varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);// Check if new maximum foundif (varBetween > varMax){varMax = varBetween;threshold = t;}}return threshold;}
}
图片验证码--BufferedImage 图片验证码去除干扰线相关推荐
- python 验证码去除干扰线,python 对验证码图片进行降噪处理
python 对验证码图片进行降噪处理 发布时间:2018-05-16 20:38, 浏览次数:962 , 标签: python 首先贴一张验证码上来做案例: 第一步先通过二值化处理把干扰线去掉: f ...
- 验证码——python去除干扰线
一.验证码识别的概念 机器识别图片主要的三个步骤为消去背景.切割字符.识别字符.而现有的字符验证码也针对这三个方面来设计强壮的验证码. 以下简图帮助大家理解验证码识别的流程: 二.处理流程 其中最为关 ...
- python去干扰线_验证码——python去除干扰线
[在上一篇文章中,我们使用sklearn对验证码进行了识别,为了提高识别率,今天来进行进一步优化. 观察验证码后,发现还可以对其进行旋转处理,这个验证码旋转角度在-30-30 一.验证码识别的概念 机 ...
- OpenCV学习第十三篇:提取水平和垂直线(去除干扰线)
1.结构元素 可以是任意形状的结构元素:矩形,圆,直线,磁盘形状,砖石形状等 2.提取步骤 输入图像彩色图像imread 转换为灰度图像cvtColor 转换为二值图像adaptiveThreshol ...
- Kaptcha 验证码 无噪点 无干扰线 配置
先看 生成的验证码图片例子: 这是原来的样子 KaptchaConfig.java 这个就不用说了吧,使用Kaptcha的基本配置类 package com.xx.config;import com. ...
- java图形验证码去除干扰,使用python 对验证码图片进行降噪处理
首先贴一张验证码上来做案例: 第一步先通过二值化处理把干扰线去掉: from PIL import Image # 二值化处理 def two_value(): for i in range(1,5) ...
- python去干扰线_GitHub - Guardiant/VerifyCode: 验证码去干扰线识别
VerifyCode 使用Python给图片去干扰线和噪点 Img.py 处理验证码,对验证码进行去燥,分割 Crack.py 破解验证码,得到验证码数据 此程序运行在Python3.5版本上,不是P ...
- java返回图片base64_java将图片转为base64返回给前端
本文实例为大家分享了java将图片转为base64返回给前端的具体代码,供大家参考,具体内容如下 一.controller端代码 @RequestMapping(value = "/capt ...
- java验证码技术_验证码技术(JavaWeb 中验证码的实现 )
二.实践 下面通过程序演示验证码产生和实现验证的过程. 1.验证码的产生 创建一个Servlet完成验证码的产生.首先通过随机数的产生类Random随机产生一个4位的验证码, 并将其存入session ...
最新文章
- 报告!插件×元宵来啦
- mysql only_full_group_by报错的问题(转)
- HDU 下沙的沙子有几粒
- python漂亮的螺旋_CANVAS 各种螺旋画出来的漂亮图案
- 7-217 树种统计 (25 分)
- increment java_post-increment, pre-increment. JAVA
- 你要清楚SEO内容优化注意事项
- JVM虚拟机详解(一)JVM与JAVA体系统结构
- H5打包成app的在线工具
- Shiro保姆级教程
- Linux的文件的权限管理
- 【剖析 | SOFARPC 框架】之SOFARPC 线程模型剖析
- 2018 总结,2019 计划
- 商务参考体系结构:企业对消费者 (B2C)
- 收到垃圾广告短信,回复“T”退订,完全没用怎么办?
- Destoon增加内容页的浏览历史记录
- 如何将视频中的音频提取出来
- python中变量名_python中变量的命名及详解
- 望尽天涯路--从理财角度看高可用
- 不讲武德(手动狗头):面试官上来就甩给我几道多线程代码题叫我手撕,我心里拔凉拔凉的~~~
热门文章
- mysql unixtime 毫秒_MySQL的FROM_UNIXTIME()和UNIX_TIMESTAMP()函数的区别
- 李宏毅老师课程:Unsupervised Learning - Word Embedding
- 博采 27 门语言之长,提升 Python 的能力
- 10 english
- 案例|政务大数据平台数据安全建设实践
- 跟我一起认识基础的元器件 Part1
- 剪绳子(动规、数论、贪心)
- 解决swfupload改变display属性后flash重新加载的问题(chome,safari内核的所有浏览器)...
- 前端开发需要学python吗_2018为什么一定要学Python? 小白专享!1部电影的时间入门python!...
- java 设置其他程序焦点_设置焦点的问题