前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >java验证码识别--2

java验证码识别--2

作者头像
井九
发布于 2024-10-12 00:06:12
发布于 2024-10-12 00:06:12
1120
举报
文章被收录于专栏:四楼没电梯四楼没电梯

java验证码识别--1

http://blog.csdn.net/problc/article/details/5794460

java验证码识别--2

http://blog.csdn.net/problc/article/details/5797507

java验证码识别--3

http://blog.csdn.net/problc/article/details/5800093

java验证码识别--4

http://blog.csdn.net/problc/article/details/5846614

java验证码识别--5

http://blog.csdn.net/problc/article/details/5983276

(本文仅用于学习研究图像匹配识别原理,不得用于其他用途。)

完整eclipse工程http://download.csdn.net/detail/problc/3829004

github地址 https://github.com/isee15/captcha-ocr

换一个字体固定,大小固定,位置不固定的验证码

还是四步。

1。图像预处理

这验证码还是很厚道的,都没有任何干扰。不用处理

2。分割

先纵向扫描,很容易分成四部分

再对每一部分横向扫描

3。训练就容易了

把分割的结果对应存成5.jpg,9.jpg,3.jpg,a.jpg 就可以了

4。识别

因为固定大小,识别跟 验证码识别--1 里面一样,像素比较就可以了。

识别结果如下,识别率100%:

源码:

代码语言:txt
AI代码解释
复制
public class ImagePreProcess2 {

	private static Map<BufferedImage, String> trainMap = null;
	private static int index = 0;

	public static int isBlack(int colorInt) {
		Color color = new Color(colorInt);
		if (color.getRed() + color.getGreen() + color.getBlue() <= 100) {
			return 1;
		}
		return 0;
	}

	public static int isWhite(int colorInt) {
		Color color = new Color(colorInt);
		if (color.getRed() + color.getGreen() + color.getBlue() > 100) {
			return 1;
		}
		return 0;
	}

	public static BufferedImage removeBackgroud(String picFile)
			throws Exception {
		BufferedImage img = ImageIO.read(new File(picFile));
		return img;
	}

	public static BufferedImage removeBlank(BufferedImage img) throws Exception {
		int width = img.getWidth();
		int height = img.getHeight();
		int start = 0;
		int end = 0;
		Label1: for (int y = 0; y < height; ++y) {
			int count = 0;
			for (int x = 0; x < width; ++x) {
				if (isWhite(img.getRGB(x, y)) == 1) {
					count++;
				}
				if (count >= 1) {
					start = y;
					break Label1;
				}
			}
		}
		Label2: for (int y = height - 1; y >= 0; --y) {
			int count = 0;
			for (int x = 0; x < width; ++x) {
				if (isWhite(img.getRGB(x, y)) == 1) {
					count++;
				}
				if (count >= 1) {
					end = y;
					break Label2;
				}
			}
		}
		return img.getSubimage(0, start, width, end - start + 1);
	}

	public static List<BufferedImage> splitImage(BufferdImage img)
			throws Exception {
		List<BufferedImage> subImgs = new ArrayList<BufferedImage>();
		int width = img.getWidth();
		int height = img.getHeight();
		List<Integer> weightlist = new ArrayList<Integer>();
		for (int x = 0; x < width; ++x) {
			int count = 0;
			for (int y = 0; y < height; ++y) {
				if (isWhite(img.getRGB(x, y)) == 1) {
					count++;
				}
			}
			weightlist.add(count);
		}
		for (int i = 0; i < weightlist.size();) {
			int length = 0;
			while (weightlist.get(i++) > 1) {
				length++;
			}
			if (length > 12) {
				subImgs.add(removeBlank(img.getSubimage(i - length - 1, 0,
						length / 2, height)));
				subImgs.add(removeBlank(img.getSubimage(i - length / 2 - 1, 0,
						length / 2, height)));
			} else if (length > 3) {
				subImgs.add(removeBlank(img.getSubimage(i - length - 1, 0,
						length, height)));
			}
		}
		return subImgs;
	}

	public static Map<BufferedImage, String> loadTrainData() throws Exception {
		if (trainMap == null) {
			Map<BufferedImage, String> map = new HashMap<BufferedImage, String>();
			File dir = new File("train2");
			File[] files = dir.listFiles();
			for (File file : files) {
				map.put(ImageIO.read(file), file.getName().charAt(0) + "");
			}
			trainMap = map;
		}
		return trainMap;
	}

	public static String getSingleCharOcr(BufferedImage img,
			Map<BufferedImage, String> map) {
		String result = "";
		int width = img.getWidth();
		int height = img.getHeight();
		int min = width * height;
		for (BufferedImage bi : map.keySet()) {
			int count = 0;
			int widthmin = width < bi.getWidth() ? width : bi.getWidth();
			int heightmin = height < bi.getHeight() ? height : bi.getHeight();
			Label1: for (int x = 0; x < widthmin; ++x) {
				for (int y = 0; y < heightmin; ++y) {
					if (isWhite(img.getRGB(x, y)) != isWhite(bi.getRGB(x, y))) {
						count++;
						if (count >= min)
							break Label1;
					}
				}
			}
			if (count < min) {
				min = count;
				result = map.get(bi);
			}
		}
		return result;
	}

	public static String getAllOcr(String file) throws Exception {
		BufferedImage img = removeBackgroud(file);
		List<BufferedImage> listImg = splitImage(img);
		Map<BufferedImage, String> map = loadTrainData();
		String result = "";
		for (BufferedImage bi : listImg) {
			result += getSingleCharOcr(bi, map);
		}
		ImageIO.write(img, "JPG", new File("result2//" + result + ".jpg"));
		return result;
	}

	public static void downloadImage() {
		HttpClient httpClient = new HttpClient();
		GetMethod getMethod = null;
		for (int i = 0; i < 30; i++) {
			getMethod = new GetMethod("http://www.pkland.net/img.php?key="
					+ (2000 + i));
			try {
				// 执行getMethod
				int statusCode = httpClient.executeMethod(getMethod);
				if (statusCode != HttpStatus.SC_OK) {
					System.err.println("Method failed: "
							+ getMethod.getStatusLine());
				}
				// 读取内容
				String picName = "img2//" + i + ".jpg";
				InputStream inputStream = getMethod.getResponseBodyAsStream();
				OutputStream outStream = new FileOutputStream(picName);
				IOUtils.copy(inputStream, outStream);
				outStream.close();
				System.out.println(i + "OK!");
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				// 释放连接
				getMethod.releaseConnection();
			}
		}
	}

	public static void trainData() throws Exception {
		File dir = new File("temp");
		File[] files = dir.listFiles();
		for (File file : files) {
			BufferedImage img = removeBackgroud("temp//" + file.getName());
			List<BufferedImage> listImg = splitImage(img);
			if (listImg.size() == 4) {
				for (int j = 0; j < listImg.size(); ++j) {
					ImageIO.write(listImg.get(j), "JPG", new File("train2//"
							+ file.getName().charAt(j) + "-" + (index++)
							+ ".jpg"));
				}
			}
		}
	}

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		// downloadImage();
		for (int i = 0; i < 30; ++i) {
			String text = getAllOcr("img2//" + i + ".jpg");
			System.out.println(i + ".jpg = " + text);
		}
	}
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
科大讯飞勾勒生成式AI输入法“模样”,开启下一代输入法革命
回顾国内第三方输入法赛道近十余年的发展,移动互联网的市场红利催生了科大讯飞、百度、搜狗等颇具规模和实力的头部厂商。与此同时,历经多年、多方角逐,第三方输入法市场进入存量阶段,升级技术、优化用户体验来挖掘存量,成为决定竞争胜负的关键。
刘旷
2023/10/30
5790
终于!年轻人不再聊骚,互联网社交变得很不一样了?
如果你最近有参加年轻人的聚会就会发现,饭桌上新的流行已不再是桌游,而是拿出手机组团开黑——玩一局《王者荣耀》。对于腾讯而言,这是一款单靠卖皮肤都可以日入1.5亿元的现象级手游,对于年轻人而言,这是一个
罗超频道
2018/04/25
1.3K0
终于!年轻人不再聊骚,互联网社交变得很不一样了?
深耕语音输入12载:讯飞输入法走向万物智能新世界
“整天都在说人工智能,可人工智能到底在哪里呢,为什么到了2022年,自动倒车入库的功能都没普及,导致科目二考试还是那么难。”除了文字上的抱怨,还特意加了张某自动驾驶企业的宣传图。
Alter聊科技
2022/11/22
7050
深耕语音输入12载:讯飞输入法走向万物智能新世界
年轻人不想恋爱,AI会是良药吗?
博主跟ChatGPT互动、聊天、“谈”恋爱,正在成为中外社交媒体平台上新的流量密码,受到大批年轻人追捧和跟风。
小腾资讯君
2024/04/26
2530
洞察 | “丧营销”与“丧文化”:营销的进阶是帮助用户表达
“丧”营销又火了。 从UCC咖啡的“丧”营销海报在Facebook爆火到“丧茶”快闪店的朋友圈刷屏,再从“Moonleaf 月葉”的消极杯到“试物所”打造的“丧”系列酸奶,“丧”这一情绪,或者说是表达
灯塔大数据
2018/04/04
1.3K0
洞察 | “丧营销”与“丧文化”:营销的进阶是帮助用户表达
卖茶女、酒托、机器人,95后年轻人的“私密社交”还“纯粹”吗?
又到毕业季,今年因为特殊原因,来得稍晚,却不妨碍又一波朝气蓬勃的年轻人步入社会,回想起去年此时,小李同学仍有些兴奋,“不知不觉就工作一年了,工作比读书更紧凑,但又少了点什么,嗯,是社交,除去在工作环境认识的人以外,一年时间好像再没有交到一个新朋友”。
用户2908108
2020/07/02
3100
卖茶女、酒托、机器人,95后年轻人的“私密社交”还“纯粹”吗?
来看看搜狗是如何通过“玩花样”抓住年轻人的
iOS开放第三方输入法才半年,搜狗输入法已进入第三个版本,这个版本最大的特色功能有些出人意料,竟然是新增了“花漾字”库,这是一种可以将用户输入的文字异形化的功能,比如让文字长耳朵、发芽、长草、长翅膀之类的。初看上去挺好玩的,朋友圈也有不少人在玩,它是昙花一现还是像火星文一样生命强劲还有待观察。我思考的是,搜狗输入法作为一款国民级输入法,如此“不正经”的背后究竟是什么逻辑,是搜狗输入法已经“无新可创”了,还是用户的需求真的在变化了?仔细分析后的结论是,用户的输入需求变化了。 输入法的创新点在哪里? 先来回顾下
罗超频道
2018/04/28
5770
1亿年轻人在Soul找到社交新选择
如今社会中,越来越多的年轻人并不满足于微信等熟人社交,他们希望有更多渠道来认识新朋友并了解世界。特别是今年就地过年的举措,让很多年轻人只能独自度过这个本该团聚的春节,而这也进一步放大了其对社交的需求。
刘旷
2021/02/20
4430
1亿年轻人在Soul找到社交新选择
做年轻人的朋友!解构小米和「大米」的品牌年轻化成功之道
4月底,5000份众筹造跑车的消息,点燃了互联网汽车圈的热情。不久前的深圳车展上,上汽MG品牌带来的名为MG Cyberster的概念跑车又再一次掀起热议,这款万众瞩目的新星不仅造型前卫,而更具话题性的是,该车还将通过众筹的方式投入生产。 众筹是一个对于广大网友并不陌生的词汇,因为被大家所熟悉的小米公司,旗下诸多产品经常采用众筹的方式来生产。而本次上汽名爵汽车竟然也采用这种方式来生产跑车,真是既大胆又前卫,也正因如此,广大网友们,亲切的给MG品牌冠以了汽车界的“Great M” (大米)称谓,二者的共同
机器之心
2023/03/29
3230
做年轻人的朋友!解构小米和「大米」的品牌年轻化成功之道
设计驱动力|玩转QQ红包社交
QQ最新版本上线了多种红包玩法及红包封皮火遍全网…接龙红包曾创造热点词“一个顶俩”收入百度百科,登上知乎热榜第一;画图红包、红包封皮等也有大量网友参与讨论…那么QQ红包作为OG产品如何保持活力,如此有趣的红包社交又是如何设计出来的? INTRO 前言 众所周知,QQ的用户群体更加年轻化;相对于支付宝和微信红包偏向于的钱包属性,QQ红包则更像是手Q生态中重要的社交工具。但近几年的数据表明用户侧对于红包的新鲜感会有所下滑。 我们对现有运营进行分析后发现了问题,目前现有封皮只针对节日推出,形象以QQfa
腾讯ISUX
2020/11/19
6070
输入法,能成为AI的新入口吗?
在今年8月a16z发布的AI全球应用榜单上,排名前十名的web端流量产品,ChatGPT和Claude两个基础模型分列第一和第四;第三和第九是AI搜索领军产品Perplixity和Liner;Character.ai和JannitorAI两个陪伴型Chatbot分列第二和第六。
小腾资讯君
2024/11/27
1750
BFF博主的走红启示录
从个人到CP再到抱团打造团体IP,制造爆点、增加出圈几率已经成为网红进化的趋势。
Alter聊科技
2023/01/31
4710
BFF博主的走红启示录
讯飞输入SDK推出“T-Sheng”功能:可模仿人聊天,自动回复信息
闲聊是我们日常生活中最基本的需求。这种被称之为“社交”的沟通方式无时无刻不存在,但你并不能每时每刻在线。手机聊天不可避免占据我们大量时间。 每个早晨睁开眼的第一件事就是看手机,每个夜晚入睡前最后一件事
BestSDK
2018/02/28
2.1K0
讯飞输入SDK推出“T-Sheng”功能:可模仿人聊天,自动回复信息
密友社交设计探索
腾讯ISUX isux.tencent.com 社交用户体验设计 1 社交现状与痛点 保持距离、经营人设、礼貌分寸,我们努力维系与迎合,去成为在社交关系中受欢迎的角色。曾几何时,人们在使用社交APP时越来越忐忑,“这句话这样说是否合适?”“是否影响到了我的公众形象?””这样会不会太矫情?”又或是,大家开始抱怨社交产品上的红点提示,似乎永远也删不完。想联系的人找不到,不想联系的,却又碍于社交礼仪,只能礼貌的客套。许多人在问,那个想说什么就说什么的“我”去了哪儿? 2 痛点分析 美国社会学家格兰
腾讯ISUX
2019/01/28
8930
密友社交设计探索
被追捧的“真实感”,社交平台的价值密码?
2022年第一季度,其月活用户数暴增315%,一度在美国、法国、英国、西班牙等多个地区的AppStore里排名前十,目前的累计下载量已经超过1000万,其中80%的用户年龄在16到24 岁之间。
Alter聊科技
2023/01/13
2470
Q语言 | 有生机的设计
已过弱冠之年的QQ不仅传递用户的信息与情感,更缩短了亿万用户的社交距离。而QQ的演进同样面临挑战,任何一个海量用户平台的进化都需谨小慎微,丰富娱乐化的社交场景日趋复杂,后浪在展现自我与社交表达的平台也有更多的选择,因此QQ需要担当起连接用户与未来的桥梁。 ♧ Q语言是什么? 人与人通过语言进行交流,而用户与QQ的体验互动我们认为也是通过一种语言进行交流,也即Q语言。为了让用户在连接未来的桥梁上通行无阻,Q语言不仅要保持一致与高效性,更需要具备打动用户的独特魅力,另外考虑到QQ在亿万用户的影响力,也应
腾讯ISUX
2020/06/24
9780
2015搜狗输入法表情数据报告 这些真相你都知道吗
2015搜狗输入法表情数据汇总,这些不易察觉的真相你都造吗? 网上聊天,人们已经习惯于使用各种生动、有趣的表情。据统计,2015年搜狗输入法全年表情发送量超过千亿次,在2.4亿月活跃用户中,超过90%
灯塔大数据
2018/04/10
9470
2015搜狗输入法表情数据报告 这些真相你都知道吗
“千人千面”的广告时代将被AI终结
DeepSeek的出圈,不仅引爆了全社会对于AI的大讨论,更重要的是激发各界人士从观望者转变为参与者,掀起了一波真实的人工智能落地潮。在孕育了AI的互联网生态中,AI引起的变化会首当其冲,且影响更彻底。广告作为互联网生态最主要的商业模式,更是当前AI技术应用的主战场。
小腾资讯君
2025/03/31
1180
人工智能时代来袭,输入法如何决胜下一个10年
近日,讯飞输入法新版本正式上线,在随声译和快捷翻译功能里增加了日译中、韩译中、泰、越、西、法、德、俄与中文互译,合计18种翻译,这也使得讯飞输入法成为中文与外语互译最多的输入法产品。
刘旷
2020/05/29
7200
人工智能时代来袭,输入法如何决胜下一个10年
Soul如何让年轻人的“灵魂”心甘情愿的买单?
社交一直是人们进行自身社会化的一项重要活动。而随着移动互联网的发展,移动互联网端的社交性活动不仅承担着人际间交往的纽带作用,同时也扮演着满足个人信息及情感表达诉求的重要角色。移动社交app更是成为了人们日常生活中用以沟通和交流不可缺少的一部分。
灵猫财经
2021/05/09
4570
推荐阅读
相关推荐
科大讯飞勾勒生成式AI输入法“模样”,开启下一代输入法革命
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档