java基于BufferedImage进行图片数字识别预处理

2023-11-13

参考文章链接:

1.https://blog.csdn.net/kobesdu/article/details/8142068

2.https://blog.csdn.net/fjssharpsword/article/details/52651845

 

一、识别图片的步骤顺序如下:

1.先使用java代码对图片的亮度、对比度、饱和度进行调整

2.对图片进行的灰度化和二值化以便更好的识别

3.使用OCR库对处理后的文件进行识别

二、图片的分类以及不同的处理办法

 1.简单图片

     图片的背景颜色比较单一的,例如红绿灯的倒计时。在图片预处理的时候只需要保留图片中的红色、绿色以及黄色即可

     颜色比较单一,代码思路就是读取图片后获取各个像素点的RGB数值,然后根据下面的阈值进行颜色替换就可以,使用的OCR白底黑字识别较高,所以替换时需要保留的替换成黑色,其余颜色全部替换白色即可。

检测所用的阈值如下

其中ThR=0.4;ThG=0.3,ThB=0.4,thy=0.85

这种方式,阈值在这个空间里很容易地找到。然而,出现了一些问题:这个标准化的空间,因为照度低(低RGB值),该转换是不稳定的,并在接近零的值,噪声被放大。

 2.复杂背景图片

     图片的背景颜色可能是一种或多种的情况。在图片预处理的时候则需要对图片进行一系列调整,测试代码如下,测试代码中的参数可能需要调整。

    //读取原图片转化为BufferedImage对象
    public static BufferedImage file2img(String imgpath) {
        try {
            BufferedImage bufferedImage=ImageIO.read(new File(imgpath));
            return bufferedImage;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
//调整图片对比度、亮度和饱和度
	public static  BufferedImage changeImage(BufferedImage src, BufferedImage dest,float contrast,float brightness){
		int width = src.getWidth();  
        int height = src.getHeight();
        if ( dest == null )  
            dest = creatCompatibleDestImage( src, null );
        int[] inPixels = new int[width*height];  
        int[] outPixels = new int[width*height];
        src.getRGB( 0, 0, width, height, inPixels, 0, width );
        
        int index = 0;  
        int[] rgbmeans = new int[3];
        double redSum = 0, greenSum = 0, blueSum = 0;  
        double total = height * width; 
        for(int row=0; row<height; row++) {  
            int ta = 0, tr = 0, tg = 0, tb = 0; 
            for(int col=0; col<width; col++) {  
                index = row * width + col; 
                ta = (inPixels[index] >> 24) & 0xff;  
                tr = (inPixels[index] >> 16) & 0xff;
                tg = (inPixels[index] >> 8) & 0xff;  
                tb = inPixels[index] & 0xff;
                redSum += tr;  
                greenSum += tg;
                blueSum +=tb; 
            }
        }
        
        rgbmeans[0] = (int)(redSum / total);  
        rgbmeans[1] = (int)(greenSum / total);  
        rgbmeans[2] = (int)(blueSum / total); 
        for(int row=0; row<height; row++) {  
            int ta = 0, tr = 0, tg = 0, tb = 0;  
            for(int col=0; col<width; col++) {           	
            	 index = row * width + col;  
                 ta = (inPixels[index] >> 24) & 0xff;  
                 tr = (inPixels[index] >> 16) & 0xff;  
                 tg = (inPixels[index] >> 8) & 0xff;  
                 tb = inPixels[index] & 0xff; 
                 
                 tr -=rgbmeans[0];  
                 tg -=rgbmeans[1];  
                 tb -=rgbmeans[2];
                 
                 tr = (int)(tr * contrast);  
                 tg = (int)(tg * contrast);  
                 tb = (int)(tb * contrast);

                 tr += (int)(rgbmeans[0] * brightness);  
                 tg += (int)(rgbmeans[1] * brightness);
                 tb += (int)(rgbmeans[2] * brightness);
                 
                 outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);
            }
        }
        setRGB( dest, 0, 0, width, height, outPixels );
		return dest;
	}
//图片灰度化
	public static BufferedImage Color2Gray(BufferedImage image){
		//BufferedImage image;
		try {
			//image = ImageIO.read(file);
			BufferedImage destImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
			ColorConvertOp cco = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
			cco.filter(image, destImage);
			//img_color_brightness(destImage, 120);			
			//ImageIO.write(destImage, "png", destFile);
			return destImage;
		} catch (Exception e1) {
			e1.printStackTrace();
			return null;
		}
		
	}
    //图片去燥二值化
	public static BufferedImage cleanImage(BufferedImage bufferedImage){

		try {
			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]);
				}
			}

			return binaryBufferedImage;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}

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;
   	}
 //保存图片,extent为格式,"jpg"、"png"等
    public static void img2file(BufferedImage img,String extent,String newfile) {
        try {
            ImageIO.write(img, extent, new File(newfile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
测试函数
public static void main(String[] args) {

        //要处理的图片目录 
        File dir = new File("D:/newreport/picTest/1");          
        //列出目录中的图片,得到数组           
        File[] files = dir.listFiles(); 

        for (int i = 0; i < files.length; i++) {
			if(files[i].isFile()){
				//读取原图片
				BufferedImage bi=file2img(files[i].getAbsolutePath().toString());  //读取图片
				//调整原图片对比度以及亮度参数 3.0f   0.5f
				BufferedImage duibi1=changeImage(bi, null,3.0f,0.5f);
				//对原图片进行灰度化
				BufferedImage huisebi = Color2Gray(duibi1);
				//灰度化图片调整对比度2.5f -1.0f
				BufferedImage duibi2 = changeImage(huisebi, null,2.5f,-1.0f);
				//图片二值化
				BufferedImage erzhibi = cleanImage(duibi2);
                //保存图片
				img2file(erzhibi,"png","D:/newreport/picTest/2/" + "test" + i + ".png");  
			}
		}
	}
    public static BufferedImage creatCompatibleDestImage(BufferedImage src,BufferedImage dest){
		return new BufferedImage(src.getWidth(),src.getHeight(),BufferedImage.TYPE_INT_RGB);
	}

 

 

 

 

 

 

 

 

 

 

 

 

 

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

java基于BufferedImage进行图片数字识别预处理 的相关文章

  • JComponent 未显示图片背景?

    我的组件没有显示 我该如何解决 Code import java awt import java awt event ActionEvent import java awt event ActionListener import java
  • Java TGA 加载器

    我正在寻找一个小型且免费的 Java 图像加载类或库 理想情况下 结果是 BufferedImage 是的 我已经用谷歌搜索过 但大多数结果都已经过时 或者是相当大的库 其中包含很多我不需要的其他东西 我正在寻找一些小而简单的东西 只能读取
  • 尽快清除透明的 BufferedImage

    我有一个使用以下代码创建的透明 BufferedImage 我认为与它的创建方式无关 GraphicsEnvironment ge GraphicsEnvironment getLocalGraphicsEnvironment Graphi
  • 扩展BufferedImage

    为什么下面的代码显示的是黑色图像而不是图片 如何正确扩展BufferedImage class SizeOfImage public static void main String args throws Exception URL url
  • 旋转具有透明背景的 BufferedImage

    我有一个具有透明背景的图像 我想将此图像旋转到特定角度并保留结果图像的透明背景 为此 我使用以下方法 public static BufferedImage rotateImage BufferedImage image double an
  • 在 Java 中打印 BufferedImage 的正确方法

    我想知道是否有正确的方法来打印BufferedImage在爪哇 基本上我已经创建了一个运行良好的照片处理程序 我可以保存图像等 但我真正的目标是将其发送到打印机软件 以便您可以选择要打印的页数和页面类型 所以我的简短问题是 如何将缓冲图像发
  • 如何从包含像素的数组创建 BufferedImage?

    我从以下位置获取像素BufferedImage使用该方法getRGB 像素存储在名为的数组中data 对数据数组进行一些操作后 我需要创建一个BufferedImage再次这样我就可以将它传递给一个模块 该模块将显示来自该数据数组的修改后的
  • 合并两个图像 --> 4 倍大小!如何减小文件大小?

    我使用下面的代码合并两个图像 一张不透明的基础图像 一张透明的覆盖图像 其拥有的图像文件大小分别为 20kb 和 5kb 合并两个图像后 生成的文件大小 gt 100kb 因此至少是 25kb 组合大小的 4 倍 我预计文件大小小于 25k
  • 当从 Java 剪贴板对象中检索为图像时,来自 Outlook 的剪贴板副本始终设置为黑色背景

    以下是申请步骤 从 html 电子邮件或网站复制一些富文本 文本 图像的组合 在您的java代码中检索从剪贴板对象复制的内容作为BufferredImage 将检索到的图像对象保存为磁盘上的图像文件 您会注意到 在保存的文件中 图像效果很好
  • 如何序列化包含 BufferedImages 的对象

    我正在尝试用 java 创建一个简单的图像编辑程序 我做了一个ImageCanvas包含有关正在编辑的图像的所有信息的对象 一些基本属性 正在应用的效果列表 BufferedImage层等 我想要一种简单的方法将其保存到磁盘 以便稍后可以再
  • 为什么这段显示图像的代码在构建到 jar 中时会出现“错误”?

    我想通过在 JLabel 上绘制 BufferedImage 来显示图像 x y Offset是在JLabel的中间绘制一个较小的图像 如果我在 IDE 中运行代码 它会正常工作并在我的 JFrame 上显示图像 如果我现在将类构建到 ja
  • 如何在android中加载BufferedImage?

    我要加载BufferedImage在我的应用程序中 为此我正在使用ImageIO但我越来越java lang NoClassDefFoundError BufferedImage tgtImg loadImage ImageD2 jpg p
  • 使用 BufferedImage 从 Java 中的 RGB 颜色空间获取灰度像素值

    任何人都知道转换从返回的 RGBint 值的简单方法
  • 如何在java中弯曲图像

    有什么办法可以弯曲BufferedImage在Java中 我认为如果我将图像裁剪成更小的部分并旋转它们 那么我基本上会弯曲图像 但它似乎不起作用 这是我创建的方法 This is a recursive method that will a
  • 序列化包含 BufferedImages 的对象

    正如标题所示 我试图将一个包含 以及其他变量 字符串等 一些 BufferedImage 的对象保存到文件中 我找到了这个 如何序列化包含 BufferedImages 的对象 https stackoverflow com questio
  • 如何缩放 BufferedImage

    按照javadocs 我尝试扩展BufferedImage没有成功这是我的代码 BufferedImage image MatrixToImageWriter getBufferedImage encoded Graphics2D grph
  • 如何判断上传的文件是图片还是其他文件?

    在我的网络应用程序中 我有一个图像上传模块 我想检查上传的文件是否是图像文件或任何其他文件 我在服务器端使用Java 图像被读作BufferedImage在java中 然后我将其写入磁盘ImageIO write 我该如何检查Buffere
  • 从 Eclipse 和命令行运行时,BufferedImage 字节具有不同的字节顺序

    我试图转换一个BufferedImage s byte 从 32 位 RGBA 到 24 位 RGB 根据这个答案 https stackoverflow com a 9470843 2581401最快的方式获得byte 从图像中可以看出
  • Java ImageWriter BufferedImage 到 GIF

    我希望你们能帮我解决这个问题 我不确定这是 Java 中的错误还是我做错了什么 但我会选择后者 我想将 BufferedImage 转换为 GIF 图像 然后我希望将 GIF 以字节数组的形式保存在内存中 我不想将文件保存到磁盘 该程序应该
  • 使用 java.awt.image.BufferedImage 创建 BIFF8 BITMAP 记录需要很多时间 - 有没有更好的方法?

    所以我正在创建一个HSSFSheet使用设置背景位图apache poi并拥有自己的低级代码 这https www openoffice org sc excelfileformat pdf https www openoffice org

随机推荐

  • 多输入多输出

    多输入多输出 MATLAB实现BP神经网络多输入多输出预测 目录 多输入多输出 MATLAB实现BP神经网络多输入多输出预测 预测效果 基本介绍 程序设计 参考资料 预测效果
  • 服务的边界

    服务边界是服务拆分和集成的前提 1 识别业务领域及边界 当前主要方法论 领域驱动设计 领域可简单理解为特定的业务系统 其中主要的设计维度为策略维度和技术维度 待完善 2 界限上下文 就是根据界限 边界 确定上下文 具体的业务场景 3 服务边
  • css3 transform + deviceorientation实现图片旋转效果

    1 陀螺仪deviceorientation的使用 参考 关于陀螺仪deviceorientation https segmentfault com a 1190000007183883 2 transform各属性的具体使用 参考 深入理
  • 计算机组成原理——单周期CPU

    单周期CPU 项目代码 实验原理 MIPS指令 rom coe文件 代码 顶层模块SingleCycleCPU display外围模块 PC instructionMemory Alu模块 DataMemory ControlUnit 旧的
  • 排序(六):归并排序

    排序算法系列文章 排序 一 冒泡排序 排序 二 选择排序 排序 三 堆排序 排序 四 插入排序 排序 五 二分搜索 排序 六 归并排序 排序 七 快速排序 排序 八 希尔排序 目录 排序算法系列文章 归并排序 Merge Sort 基本思想
  • Python之文件的读写

    文章目录 前言 一 打开和关闭文件 open和close 1 打开文件 2 关闭文件 mode的方式 几种读取文件的函数 写入文件的函数 二 with open as操作文件 1 with open as与open close的区别 总结
  • Ubuntu部署OpenStack zed版本neutron报错:Feature ‘linuxbridge‘ is experimental and has to be explicitly enab

    系统版本 Ubuntu 22 04 1 LTS OpenStack版本 zed 组件 Neutron 组件报错内容 Feature linuxbridge is experimental and has to be explicitly e
  • GLSL中texture3D获得的值大小

    使用OpenGL的glTexImage3D 获得纹理数据 再在片元着色器对数据进行处理texture3D 得到的数据已被压缩到0 1 openGL函数glTexImage3D导入数据后 在GLSL中 数据被进行了压缩 glTexImage3
  • python3GUI--音乐播放器(精简版)By:PyQt5(附下载地址)

    文章目录 一 前言 二 预览 1 主界面 2 歌单页 3 歌词页 4 播放列表 5 mini 6 设置 三 心得 1 解耦 2 体验优化 3 歌词显示 4 双击歌曲后发生什么 四 总结 一 前言 传送门 1 python3GUI 打造一款音
  • 关于Linux下的pid文件

    1 pid文件的内容 用cat命令查看 可以看到内容只有一行 记录了该进程的ID 2 pid文件的作用防止启动多个进程副本 3 pid文件的原理进程运行后会给 pid文件加一个文件锁 只有获得pid文件 固定路径固定文件名 写入权限 F W
  • Elasticsearch聚合分析、mget批量查询、bulk批量更新

    Elasticsearch分组集合 一 分组聚合操作 开启fielddata属性 1 在ElasticSearch中默认fielddata默认是false的 因为开启Text的fielddata后对内存的占用很高 如果进行聚合查询时候就需要
  • Redfish协议测试工具–Postman

    1 工具和资料获取 2 简单使用说明 1 GET类举例 2 PATCH类举例 3 常见命令 1 工具和资料获取 Postman工具获取 服务器Redfish接口说明文档 使用前必读接口文档中 适用的产品 查看自己的服务器是否支持此协议 2
  • 简单sql注入

    报错注入找列数 确定为16 联合查询找回显点 查询数据库和数据库版本 版本为5 0以上 需要对查询的内容加密否则报错 结果不是需要的 查询所有的表 获得表名cms users 获得字段usename password 得到账号密码
  • 用java代码验证char类型数据占几个字节

    char为字符型数据 储存单个字符 但阿拉伯数字 英文字母 标点符号等皆为字符型数据 占用字节看似错综复杂 但是char也为脱离计算机基本 二进制储存机制 char本质上内存中皆存储字符编码 1 127为ASCII码 也就是常用的字符 但在
  • 关于iOS9中的App Transport Security(ATS)相关说明及适配

    iOS9中新增App Transport Security 简称ATS 特性 主要使到原来请求的时候用到的HTTP 都转向TLS1 2协议进行传输 这也意味着所有的HTTP协议都强制使用了HTTPS协议进行传输 原文如下 App Trans
  • VS2010:error C2061: 语法错误

    实例 类名 类中包含的头文件 point iostream line point flat flat line 输出错误 error C2061 语法错误 标识符 flat 解决办法 前置声明 line h class flat
  • 区块链读书笔记04 - 以太坊

    区块链读书笔记04 以太坊 以太坊 Ethereum 以太坊关键概念 账户 Account 交易 Transaction 消息 Messsage Gas 合约 contract 以太坊虚拟机 EVM DApp 去中心化应用 以太坊架构 以太
  • 网站域名服务器加密,网站域名利用https防劫持方法

    原标题 网站域名利用https防劫持方法 公共 DNS HttpDNS 的部署成本过高 并且具有一定的技术门槛 在面对无孔不入的 DNS 劫持时有时候其实有点力不从心 那么如何简单有效低成本的加强域名防劫持呢 只需要给网站开启 HTTPS
  • mysql jdbc 多数据源_springboot多数据源(oracle、mysql)

    1 application properties配置 server port 8085 server tomcat uri encoding utf 8 MySQL spring datasource primary driver clas
  • java基于BufferedImage进行图片数字识别预处理

    参考文章链接 1 https blog csdn net kobesdu article details 8142068 2 https blog csdn net fjssharpsword article details 5265184