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识别复杂验证码+图像处理 的相关文章

随机推荐

  • 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