JAVA识别复杂验证码+图像处理

2023-11-03

 先对验证码进行简单的处理噪点和纯色

例未曾处理的图片

public static void main(String[] args) throws Exception {
   //源文件
  String picName = "C:\\Users\\syxy101\\Desktop\\6.jpg";

 File filepic=new File(picName);
//去噪点 并处理为纯色
  BufferedImage bufferedImage = removeBackgroud(picName);
//处理后图片地址
File w2 = new File("C:\\Users\\syxy101\\Desktop\\5.png");//可以是jpg,png格式
ImageIO.write(bufferedImage, "jpg", w2);//不管输出什么格式图片,此处不需改动


}

//去除图片噪点  并将彩色转为纯色(黑色)
  public static BufferedImage removeBackgroud(String picFile)
            throws Exception {
        BufferedImage img = ImageIO.read(new File(picFile));
        int width = img.getWidth();
        int height = img.getHeight();
        for (int x = 0; x < width; ++x) {
            for (int y = 0; y < height; ++y) {
                if (isWhite(img.getRGB(x, y)) == 1) {
                    img.setRGB(x, y, Color.WHITE.getRGB());
                } else {
                    img.setRGB(x, y, Color.BLACK.getRGB());
                }
            }
        }
        return img;
    }
//设置颜色阀值
 public static int isWhite(int colorInt) {
        Color color = new Color(colorInt);
        if (color.getRed() + color.getGreen() + color.getBlue() > 200 && color.getRed() + color.getGreen() + color.getBlue()<500) {
            return 0;
        }
        return 1;
    }

处理后

可以看到已经清晰了不少  当然现在还是无法识别的

一下步 强加黑色 处理掉横线斜线 噪点

package com.adc.da.sync.web;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;

import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * //TODO 添加类/接口功能描述
 *
 * @author zhangsj
 * @date 2018-12-13
 */
public class ImagePreProcess4 {



        public static void main(String[] args) throws IOException
        {
            //源文件
            File testDataDir = new File("C:\\Users\\syxy101\\Desktop\\5.png");
            //处理后路径
            final String destDir = "C:\\Users\\syxy101\\Desktop\\ss";
                cleanLinesInImage(testDataDir, 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;
        }
    }

 

 

已经去掉多余的横线和噪点了 

这时候识别度已经很高了 

为了达到识别度百分之80

需要把每个字母隔开 分开识别

  public static void main(String[] args) throws Exception {

   int x=6;
      for(int i=0;i<4;i++){
            if(i==0){
                x=6;
            }else if(i==1){
                x=22;
            }else if(i==2){
                x=36;
            }else if(i==3){
                x=52;
            }
            imageCut(x,0,15,30,picName,"D:\\ccccc"+i+".jpg");

        }

}
   /**
     * 图片剪裁
     * @param x 距离左上角的x轴距离
     * @param y 距离左上角的y轴距离
     * @param width 宽度
     * @param height 高度
     * @param sourcePath 图片源
     * @param descpath 目标位置
     */
    public static void imageCut(int x, int y, int width, int height, String sourcePath, String descpath) {
        FileInputStream is = null;
        ImageInputStream iis = null;
        try {
            is = new FileInputStream(sourcePath);
            String fileSuffix = sourcePath.substring(sourcePath.lastIndexOf(".") + 1);
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(fileSuffix);
            ImageReader reader = it.next();
            iis = ImageIO.createImageInputStream(is);
            reader.setInput(iis, true);
            ImageReadParam param = reader.getDefaultReadParam();
            Rectangle rect = new Rectangle(x, y, width, height);
            param.setSourceRegion(rect);
            BufferedImage bi = reader.read(0, param);
            ImageIO.write(bi, fileSuffix, new File(descpath));
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                is = null;
            }
            if (iis != null) {
                try {
                    iis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                iis = null;
            }
        }
    }

 

换了个验证码剪辑

这时候识别度已经到百分之90了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA识别复杂验证码+图像处理 的相关文章

  • Java - 因内存不足错误而关闭

    关于如何最好地处理这个问题 我听到了非常矛盾的事情 并且陷入了以下困境 OOME 会导致一个线程崩溃 但不会导致整个应用程序崩溃 我需要关闭整个应用程序 但不能 因为线程没有剩余内存 我一直认为最佳实践是让它们离开 这样 JVM 就会死掉
  • 如何使用Spring WebClient进行同步调用?

    Spring Framework in 休息模板 https docs spring io spring framework docs current javadoc api org springframework web client R
  • 获取文件的锁

    我想在对特定文件开始 threo read 时获取文件上的锁定 以便其他应用程序无法读取已锁定的文件并希望在线程终止时释放锁定文件 您可以获得一个FileLock https docs oracle com javase 8 docs ap
  • 带有 Android 支持库 v7 的 Maven Android 插件

    我使用 maven android plugin 构建我的 android 应用程序 它依赖于 android 支持库 v4 和 v7 由于我没有找到如何从developer android com下载整个sdk 因此我无法使用maven
  • 使用 WebDriver 单击新打开的选项卡中的链接

    有人可以在这种情况下帮助我吗 场景是 有一个网页 我仅在新选项卡中打开所有指定的链接 现在我尝试单击新打开的选项卡中的任何一个链接 在下面尝试过 但它仅单击主 第一个选项卡中的一个链接 而不是在新选项卡中 new Actions drive
  • 如何强制jar使用(或jar运行的jvm)utf-8而不是系统的默认编码

    我的Windows默认编码是GBK 而我的Eclipse完全是utf 8编码 因此 在我的 Eclipse 中运行良好的应用程序崩溃了 因为导出为 jar 文件时这些单词变得不可读 我必须在 bat 文件中写入以下行才能运行该应用程序 st
  • Base36 编码字符串?

    我一直在网上查找 但找不到解决此问题的方法 在 Python Ruby 或 Java 中 如何对以下字符串进行 Base 36 编码 nOrG9Eh0uyeilM8Nnu5pTywj3935kW 5 Ruby 以 36 为基数 s unpa
  • Reactive Spring 不支持 HttpServletRequest 作为 REST 端点中的参数?

    我创建了一个 RestController 如下所示 RestController public class GreetingController RequestMapping value greetings method RequestM
  • Logback:SizeAndTimeBasedRollingPolicy 不遵守totalSizeCap

    我正在尝试以一种方式管理我的日志记录 一旦达到总累积大小限制或达到最大历史记录限制 我最旧的存档日志文件就会被删除 当使用SizeAndTimeBasedRollingPolicy在 Logback 1 1 7 中 滚动文件追加器将继续创建
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 添加到列表时有没有办法避免循环?

    我想知道这样的代码 List
  • 通过 appassembler-maven-plugin 生成的脚本无法在 Spring Boot 应用程序中找到主类

    我使用 appassembler maven plugin 生成的启动脚本有问题 我有一个基本的 spring boot 应用程序 只有一个类 SpringBootApplication public class ScriptDemoApp
  • Spring Data JPA:查询如何返回非实体对象或对象列表?

    我在我的项目中使用 Spring Data JPA 我正在演奏数百万张唱片 我有一个要求 我必须获取各种表的数据并构建一个对象 然后将其绘制在 UI 上 现在如何实现我的 Spring 数据存储库 我读到它可以通过命名本机查询来实现 如果指
  • 寻找局部最小值

    下面的代码正确地找到了数组的局部最大值 但未能找到局部最小值 我已经进行了网络搜索 以找到找到最小值的最佳方法 并且根据这些搜索 我认为我正在使用下面的正确方法 但是 在几天的时间里多次检查每一行之后 下面的代码中有一些我仍然没有看到的错误
  • JAVA中遍历JSON数据

    我是 JSON 新手 我使用 HTTPUrlConnections 并在 JAVA 程序中获得一些响应 响应数据将类似于 data id 1 userId 1 name ABC modified 2014 12 04 created 201
  • IntelliJ 组织导入

    IntelliJ 是否具有类似于 Eclipse 中的组织导入功能 我拥有的是一个 Java 文件 其中多个类缺少导入 例子 package com test public class Foo public Map map public J
  • 无需登录即可直接从 Alfresco 访问文件/内容

    我的场景是这样的 我有一个使用 ALFRESCO CMS 来显示文件或图像的 Web 应用程序 我正在做的是在 Java servlet 中使用用户名和密码登录 alfresco 并且我可以获得该登录的票证 但我无法使用该票证直接从浏览器访
  • 如何让 Emma 或 Cobertura 与 Maven 一起报告其他模块中源代码的覆盖率?

    我有一个带有 Java 代码的多模块 Maven 设置 我的单元测试在其中一个模块中测试多个模块中的代码 当然 这些模块具有相互依赖性 并且在测试执行之前根据需要编译所有相关模块中的代码 那么 如何获得整个代码库覆盖率的报告 注意 我不是问
  • 使用 Java https 上传到 Imgur v3 错误

    我目前正在尝试使用他们当前的 API v3 上传到 imgur 但是我不断收到错误 错误 javax net ssl SSLException 证书中的主机名不匹配 api imgur com imgur com OR imgur com
  • 基于 Spring Boot 的测试中的上下文层次结构

    我的 Spring Boot 应用程序是这样启动的 new SpringApplicationBuilder sources ParentCtxConfig class child ChildFirstCtxConfig class sib

随机推荐

  • Linux之执行一个可执行文件

    Linux中执行一个可执行文件 在Linux系统中执行一个可执行文件 只需写正确文件路径 即可执行文件 不需要写命令 1 如果执行当前路径下的文件 文件名 2 执行非当前目录下的文件 文件的绝对路径 注意 以上操作的前提条件 文件是可执行文
  • 想从事区块链开发? 你应该这么做

    凭借每年15 4万美元的平均工资和稳定的就业增长 现在是学习区块链开发的理想时机 为了创建和改进区块链技术 区块链开发人员练习各种技能 包括计算机网络 密码学 算法和数据结构 这些开发人员负责设计以特定业务模型为中心的区块链技术 然后构建
  • 设计模式入门(二)观察者模式

    设计模式入门 本系列所有内容参考自 HeadFirst设计模式 因为书中的代码是采用java语言写的 博主这里用C 语言改写 这里采用讲故事的方式进行讲解 若有错误之处 非常欢迎大家指导 设计模式 模式不是代码 而针对设计问题的通用解决方案
  • unity打包出现 Failed to re-package resources

    unity打包出现 Failed to re package resources unity打包出现 Failed to re package resources 在对新项目打包发布的时候出现报错提示 这个问题我搜了很多博客都没有答案 最后
  • Visual Studio Code安装支持Lua并打开函数列表

    Visual Studio Code安装支持Lua并打开函数列表 文章目录 Visual Studio Code安装支持Lua并打开函数列表 一 下载安装 1 下载 2 windows下安装 以下过程适用于1 44 2版本 3 win10下
  • 从零用自己数据跑R3LIVE

    1 相机内参标定 相机选用4mm的广角相机 相机内参标定选择用最常见的棋盘格方法 首先安装ROS自带的包 sudo apt install ros melodic camera calibration 用usb cam启动相机后进行标定 r
  • 【JS】npm electron 开发桌面应用-npm run-script package打包

    一 准备工作 首先 我们要安装electron prebuilt 它是一个npm模块 因此我们可以使用Npm来进行安装 它是一个electron的预编译版本 cnpm install g electron prebuilt 接下来安装ele
  • [已解决]WARNING: IPv4 forwarding is disabled

    问题描述 docker info WARNING IPv4 forwarding is disabled WARNING bridge nf call iptables is disabled WARNING bridge nf call
  • 字符串题目:设计 Goal 解析器

    文章目录 题目 标题和出处 难度 题目描述 要求 示例 数据范围 解法 思路和算法 代码 复杂度分析 题目 标题和出处 标题 设计 Goal 解析器 出处 1678 设计 Goal 解析器 难度 2 级 题目描述 要求 请你设计一个可以解释
  • C++硬币问题

    include
  • Unity3D引用dll打包发布的问题及解决

    今年我们开始使用Unity3D开发MMORPG 脚本语言使用C 这样我们就可以使用以往积累的许多类库 但是 在U3D中使用 NET dll的过程并不是那么顺利 比如我们今天遇到的这种问题 一 问题出现 我们在当前的一个U3D项目中使用了St
  • gin框架23--绑定 HTML 复选框

    gin框架23 绑定 HTML 复选框 介绍 案例 说明 介绍 本文通过一个简单的案例 将结构体和html中的 form 数据绑定在一起 案例 源码 main go package main import github com gin go
  • 裸设备和Oracle问答20例

    1 什么叫做裸设备 裸设备 也叫裸分区 原始分区 是一种没有经过格式化 不被Unix通过文件系统来读取的特殊字符设备 它由应用程序负责对它进行读写操作 不经过文件系统的缓冲 2 如何辨别裸设备 在Unix的 dev 目录下 有许多文件 其中
  • 【C++设计模式】开放-封闭原则

    2023年8月27日 周日下午 我觉得我的这篇博客还是写得很不错的 哈哈哈 目录 概述 举例说明 用开放 封闭原则重构 概述 开放 封闭原则 Open Closed Principle OCP 是面向对象设计中的一个重要原则 也是许多设计模
  • shineblink CoreTFT串口屏开发

    TFT液晶触摸屏 一 开发基础准备工作 二 本章节实现功能介绍 三 接线图 四 开发板端完整代码 五 液晶屏页面的开发 六 代码运行结果 Shineblink Core 可支持3 5寸 4寸 7寸的TFT串口彩色液晶屏 本篇章主要演示了TJ
  • Windows 常用快捷键

    常用快捷键 Ctrl C 复制选定项 Ctrl X 剪切选定项 Ctrl V 粘贴选定项 Ctrl Z 撤消操作 Ctrl Y 重做操作 Ctrl S 保存 Ctrl A 选择文档或窗口中的所有项目 Alt Tab 在打开的应用之间切换 W
  • Qt Utils : To-Do

    Qt Creator自带的todo插件工具 真心舒爽 特别是对于我这种记不住三天前自己写的shit mountain的 渣渣CXY来讲 边撸代码边注释 快速查阅Task 非常重要 1 上效果图 2 工具使用 1 勾选使用插件 重启Qt Cr
  • 7-32 统计MOOC证书

    本题要求编写程序 输入N个学生的MOOC成绩 统计优秀 合格证书的数量 以及没有获得证书的数量 学生修读程序设计MOOC 85分及以上获得优秀证书 不到85分但是60分及以上获得合格证书 不到60分则没有证书 输入格式 输入在第一行中给出非
  • 如何安装新的PHP扩展模块

    一 phpize方式 该方法用于安装php源码ext目录中没有的扩展 1 下载源码 2 解压并进入扩展目录 3 执行phpize 4 执行 configure 5 make make install 6 在php ini 文件中添加 ext
  • JAVA识别复杂验证码+图像处理

    先对验证码进行简单的处理噪点和纯色 例未曾处理的图片 public static void main String args throws Exception 源文件 String picName C Users syxy101 Deskt