`
otom31
  • 浏览: 229303 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

java 实现一维条码图片识别 开发总结

阅读更多

花了半天时间,搞定了条码图片的分析和识别,java 实现的,容错率还是挺高的;

 

对不住了,最近项目太近啊,要想的事情太多了,我就只有贴代码了,代码仅供参考,只实现了EAN-13码,只要有了这个思路和去噪算法,可以扩展其他的识别算法! 其实最关键的就是解决降噪的问题,我采用方差降噪法,算法简单,效率也高,成功率也不错!

 

另外关于摄像头扫描条码,google 上有个知名的开源项目,做的很好,基本上现在android 的程序都用的他;

 


代码如下

 

/**
 * 用来识别EAN13方式编码的图片
 * 图片高度像素必须大于 30px,宽度像素必须大于 200px
 * 图片区域内只包含条码和空白部分,且左右两端的空白部分必须在 10%-20%左右
 * @author tangkf
 */
public class EAN13Reader {
	static int HEIGHT	= 6;	//截取的样本图像像素高度
	static int BW_MID	= 100;	//判断黑白的阀值
	
	static int [][] LEFT_TABLE_INT		= new int[] []{
		{3,2,1,1},{2,2,2,1},{2,1,2,2},{1,4,1,1},{1,1,3,2},
		{1,2,3,1},{1,1,1,4},{1,3,1,2},{1,2,1,3},{3,1,1,2},
		{1,1,2,3},{1,2,2,2},{2,2,1,2},{1,1,4,1},{2,3,1,1},
		{1,3,2,1},{4,1,1,1},{3,1,2,1},{3,1,2,1},{2,1,1,3}
	};
	static int [][] RIGHT_TABLE_INT		= new int[] []{
		{3,2,1,1},{2,2,2,1},{2,1,2,2},{1,4,1,1},{1,1,3,2},
		{1,2,3,1},{1,1,1,4},{1,3,1,2},{1,2,1,3},{3,1,1,2}
	};
	
	/**
	 * 测试
	 * @author tangkf
	 * @param args
	 */
	public static void main(String[] args) {
		long a	= System.currentTimeMillis();
		String src	= "f:/tm-01.jpg";
		BufferedImage img	= getImg(src);
		long b	= System.currentTimeMillis();
		System.err.println("读取图片耗时:"+(b-a)+" ms");
		System.out.println("解码结果:"+getRealValue(img));
		long c	= System.currentTimeMillis();
		System.err.println("图片解码耗时:"+(c-b)+" ms");
	}

	/**
	 * 根据条码图像区域返回条码数据
	 * @author tangkf
	 * @param img 图像区域
	 * @return
	 */
	public static String getRealValue(BufferedImage img){
		int w	= img.getWidth();
		int h	= img.getHeight();
		int y	= (int)(h/2);
		if(y<HEIGHT){
			return "无法识别的条码";
		}
		
		if(h>HEIGHT*2) y= (int)(h/2)-(HEIGHT/2); else y = 1;
		
		StringBuffer valuestr	= new StringBuffer("");
		int chg	= 0;	//记录颜色变化次数
		int gvn	= 0;	//记录实际取值次数(每变化一次取值一次)
		int ln	= 0;	//记录同色连续像素的数量
		int uprv= -1;	//记录上次的像素取值
		int xdv	= 0;	//参考底色,取前8个像素的颜色作为底色参考值
		int[]	gvalue	= new int[4];	//临时记录一组数字
		
		for(int i=0;i<w;i++){
			int v	= 0;	//记录取值为深色的次数
			
			//高度取HEIGHT个像素,并求平均值,如果平均值为浅色,那么取0,否则取1
			for(int j=y;j<y+HEIGHT;j++){
				int prgb	= getValue(img.getRGB(i,j));
				xdv += prgb;
				if(prgb<BW_MID-80) v+=1;	//累加该列为深色的像素个数
			}
			int rv	= 0;
			if(i<8){
			//取参考颜色样本,默认都为0
				rv	= 0;
				BW_MID	= xdv/((i+1)*(HEIGHT));	//不断变换参考样本值
			}else{
				rv	= v>HEIGHT/2?1:0;	//n个以上的像素为深色,就表示该列为深色
			}
			
			if(rv==uprv){
				ln++;
			}else{
				chg++;	//变化次数+1 
				if(chg>1 && chg<6){
				//起始符号
					gvalue[(chg-2)%4]	= ln;
					if((chg-1)%4==0){
						valuestr.append(getSTDValue(gvalue, LEFT_TABLE_INT));
						//System.err.println(gvalue[0]+""+gvalue[1]+gvalue[2]+gvalue[3]);
					}
				}
				if((chg>5 && chg<30)|| (chg>34 && chg<59)){
					gvn++;
					if(gvn%4==0){
						gvalue[(gvn-1)%4]	= ln;
						if(gvn<=24){
							valuestr.append(getSTDValue(gvalue, LEFT_TABLE_INT));
							//valuestr.append(ln+ " RV:"+ getSTDValue(gvalue, LEFT_TABLE_INT) + "\n");
						}else{
							valuestr.append(getSTDValue(gvalue, RIGHT_TABLE_INT));
							//valuestr.append(ln+ " RV:"+ getSTDValue(gvalue, RIGHT_TABLE_INT) + "\n");
						}
					}else {
						gvalue[(gvn-1)%4]	= ln;
					}
				}
				ln	= 1;
			}
			uprv	= rv;
		}
		return valuestr.toString();
	}
	
	/**
	 * 由一组样本与基准表通过方差和的方式去噪求值
	 * @param mvalues
	 * @param STDTABLE
	 * @return
	 */
	public static int getSTDValue(final int[] mvalues,int[][] STDTABLE){
		int rvalue	= 0;
		int fx	= 0;
		for(int i=0;i<STDTABLE.length;i++){
			int[] svalues	= LEFT_TABLE_INT[i];	//基准值
			int[] xvalue	= new int[4];
			for(int j=0;j<mvalues.length;j++){
				xvalue[j]	= (int)((double)mvalues[j]/svalues[j]+0.5);
			}
			int tmp	= getFX(xvalue);
			
			if(i==0){
				fx	= tmp;
			}else{
				if(tmp<fx){
					fx	= tmp;
					rvalue	= i>9?i-10:i;	
				}
			}
		}
		return rvalue;
	}
	
	/**
	 * 求一组样本数的方差和(针对所有样本数都相同的情况简化算法)
	 * @param numlist
	 */
	public static int getFX(int[] numlist){
		if(numlist.length<1) return 0;
		int fx	= 0;
		double avg	= 0;
		for(int i=0;i<numlist.length;i++){
			avg	+= numlist[i];
		}
		avg	= (int)((double)avg/numlist.length+0.5);
		
		for(int i=0;i<numlist.length;i++){
			fx	+= (numlist[i]-avg)*(numlist[i]-avg);
		}
		return fx;
	}
	
	/**
	 * 由色彩值返回单色信号 1 或 0
	 * @param rgb
	 * @return
	 */
	public static int getValue(int rgb){
		int r	= (rgb>>16)&255;
		int g	= (rgb>>8)&255;
		int b	= rgb&255;
		double avg	= 0.299*r+0.587*g+0.114*b; //判断黑白
		return (int)avg;
	}
	
	/**
	 * 读取图片
	 * @param srcImg
	 * @return
	 */
	public static BufferedImage getImg(String srcImg){
		BufferedImage img	= null;
		try {
			img	= ImageIO.read(new File(srcImg));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return img;
	}
}
 

 

  • 大小: 4 KB
2
2
分享到:
评论
4 楼 otom31 2014-08-26  
wanmeilingdu 写道
楼上说的开源项目是什么?ZXING?

是的,ZXING
3 楼 wanmeilingdu 2014-08-25  
楼上说的开源项目是什么?ZXING?
2 楼 otom31 2012-05-04  
这个是当初我做的一个分析测试,我建议你还是用开源项目吧;
开源项目很全的,一维码,二维码,以及各种条码标准都支持的!
1 楼 qinyonghui 2012-05-04  
你这个貌似是根据图片的那种什么定义法来解析的,但是我扫码只扫了一半也能解析出来,有办法改进吗?我现在也在解析一维码和二维码,通过图片解析。谢谢

相关推荐

    java条形码识别

    Java条形码识别技术主要涉及的是对一维和二维条形码进行解码的过程,它在物流、零售、仓储管理等领域广泛应用。在这个场景中,我们关注的焦点是Google提供的ZXing(Zebra Crossing)库,这是一个开源项目,专门用于...

    C#开发的识别图片条形码

    2. BarcodeReader.NET:专门用于.NET平台的一维条形码识别库,支持多种一维条形码格式。 3. Dynamsoft Barcode Reader:提供高性能的条形码识别服务,支持一维和二维条形码,且提供了C#的API接口,方便集成到项目中...

    Spire.Barcode for Java - Java 一维和二维条码快速生成和识别组件

    Spire.Barcode for JAVA 是一款Java条形码组件,开发人员可以使用它在Java应用程序中简洁快速地生成和识别多种一维和二维条码。下载以后解压缩,然后从lib文件夹下导入Spire.Barcode.jar包到你的Java应用程序中即可...

    条码识别zbar一次识别多个条码.rar

    在IT行业中,条形码识别是一项重要的技术,广泛应用于零售、物流、仓储等多个领域。本资源"条码识别zbar一次识别多个条码.rar"是一个C#应用源码,专门针对如何使用ZBar库实现一次性识别多个条码的场景。ZBar是一个...

    OPENCV条形码定位与识别

    接下来是条形码识别的过程。在描述中提到了ZBar,这是一个专门用于读取一维和二维条码的库,它可以与OpenCV结合使用。在OpenCV中找到条形码的位置后,ZBar会进行解码,将条形码的图像转换为可读的数据。这个过程包括...

    java 条形码制作和识别

    四、条形码识别 识别条形码通常也需要借助`ZXing`库。以下是一个简单的条形码扫描器示例: ```java import com.google.zxing.*; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import ...

    google zxing读取、生成一维码、二维码图片

    ZXing(Zebra Crossing)是Google开发的一个开源项目,专门用于处理一维条形码和二维二维码的生成与读取。这个项目的名字来源于其英文名的首字母缩写,象征着“斑马线”,寓意在数据世界中指引信息的交汇。ZXing提供...

    条形码一维码生成代码

    总结来说,条形码一维码生成代码的核心是将文本信息转换成符合标准的条形码图案。在移动端和PC端,这项技术被广泛应用于快速数据输入、商品识别和自动化流程中。通过使用相应的编程库,开发者可以轻松地在各种平台上...

    一维码二维码生成识别工具barcode4j

    总结来说,barcode4j作为一个强大的一维码和二维码生成器,不仅简化了开发过程,还提供了丰富的编码格式选择。对于需要在Java项目中集成条码或二维码生成功能的开发者而言,barcode4j是一个非常实用的解决方案。在...

    生成一维条形码

    本教程将聚焦于如何使用Java编程语言来生成一维条形码,并结合提供的jar包实现这一功能。 首先,我们需要理解一维条形码的基本概念。一维条形码通常由黑白相间的线条(条)和空白(空)组成,它们代表一组数字或...

    JAVA一,二维码图片解析识别为数据

    只需要调用对应的条形码格式(如UPC-A或EAN-13)的`decode()`方法,即可实现一维条形码的识别。 在实际应用中,二维码和一维码解析功能常用于数据录入、追踪物流信息、移动支付等场景。了解并掌握这些技术对于开发...

    java解析生成一维码二维码源码加相关的jar包

    总结起来,这个资源包提供了一个完整的Java解决方案,用于生成和解析一维码和二维码。`CodeServer.java`和`CodeTest.java`是关键的实现类,它们利用ZXing库进行编码和解码操作。开发者可以通过这两个类的源代码学习...

    Python zxing 库(条形码二维码识别)

    总结,Python ZXing库提供了一种方便的方式来集成二维码和条形码识别功能到Python项目中,它允许开发者利用强大的ZXing库来处理各种类型的条码和二维码,无需编写复杂的图像处理代码。通过理解和熟练使用这个库,...

    Android_条码扫描器_一维条形码_二维QR码_apk_源码

    这个"Android_条码扫描器_一维条形码_二维QR码_apk_源码"压缩包文件很可能是ZXing库的一个实现,包含了完整的Android应用源码,用于演示如何在Android项目中集成和使用ZXing进行条码扫描。 1. **ZXing库介绍** ...

    一维条形码

    在IT行业中,一维条形码是一种常见的数据表示和识别技术,广泛应用于商品标识、物流管理、库存控制等领域。本文将深入探讨C#编程环境下如何生成和使用一维条形码,以及相关的技术要点。 一维条形码,如EAN-13、UPC-...

    初学Itext 生成PDF 表格,条形码(一维),图片

    对于初学者来说,使用iText库生成PDF表格、一维条形码以及在PDF中插入图片是一项基础但十分重要的技能。以下内容将详细介绍这些知识点,并提供一些基本的代码示例来帮助理解。 首先,iText库中生成PDF表格的能力让...

    java实现条形码编程,完整项目

    ZXing是一个开源的多格式一维/二维条码图像处理库,而JaBaAPI专注于生成各种一维条形码。这些库提供API,可以方便地在Java程序中创建条形码。 2. **条形码类型**:不同的应用场景可能需要不同类型的条形码,如Code ...

    一维条码生成控件

    一维条码生成控件是IT领域中一种用于创建条形码图像的工具,尤其在Java编程语言中广泛应用。在本文中,我们将深入探讨一维条码的基本概念、生成过程以及如何在Java环境中实现一维条码的创建,并结合"BarcodeTest"这...

    Java实现图片扫描码

    2. **Zxing库**:Zxing是一个开源的Java库,支持多种一维和二维条码格式,包括UPC-A、EAN-13、Code 128、QR Code等。在这个项目中,`rvision.jar`和`r1dvision.jar`可能是Zxing的特定版本或者封装版,用于条形码识别...

    一维条码下载

    一维条码是一种常见的数据表示和自动识别技术,在零售、物流、仓储管理等多个领域广泛应用。它的基本原理是将数字或字母编码为不同宽度的黑色和白色条纹,这些条纹可以被专门的条码扫描器读取并转化为计算机可理解的...

Global site tag (gtag.js) - Google Analytics