热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java条形码识别_javaopenCV识别条形码

我在尝试使用javaopenCV识别条形码。在花边框时却这样。我初步判断是,计算面积出现问题。System.out.println(WelcometoOpenCV

我在尝试使用java openCV 识别条形码。在花边框时却这样。

我初步判断是,计算面积出现问题。

067e77272594000800a3d13c82e00194.png

System.out.println("Welcome to OpenCV "+Core.VERSION);

Mat m = new Mat(5,10, CvType.CV_8UC1,new Scalar(0));

System.out.println("OpenCV:"+m);

Mat srcImage = Imgcodecs.imread("C:\\Users\\13543\\Desktop\\timg.jpg");//原始

Mat grayImage = new Mat();//灰色

Mat gradientXImage = new Mat();

Mat gradientYImage = new Mat();

Mat gradientImage = new Mat();

Mat blurImage = new Mat();//降噪图

Mat thresholdImage = new Mat();

Mat morphImage = new Mat();

Mat resultFileNameSring = new Mat();

ImageViewer imageViewer = new ImageViewer(srcImage, "原图");

imageViewer.imshow();

if(srcImage.empty()){

System.out.println("image file read error");

return;

}

//图片转为灰度图片

if(srcImage.channels()==3){

Imgproc.cvtColor(srcImage,grayImage,Imgproc.COLOR_RGB2GRAY);

}else{

grayImage = srcImage.clone();

}

new ImageViewer(grayImage, "灰色图").imshow();

//建立图像的梯度幅值(滤波器)

Imgproc.Scharr(grayImage,gradientXImage,CvType.CV_32F,1,0);

Imgproc.Scharr(grayImage,gradientYImage,CvType.CV_32F,0,1);

//因为我们需要的条形码在需要X方向水平,所以更多的关注X方向的梯度幅值,而省略掉Y方向的梯度幅值

Core.subtract(gradientXImage,gradientYImage,gradientImage);

//归一化为八位图像

Core.convertScaleAbs(gradientImage,gradientImage);

//看看得到的梯度图像是什么样子

new ImageViewer(gradientImage, "3图").imshow();

//对图片进行相应的模糊化,使一些噪点消除

Imgproc.blur(gradientImage,blurImage,new Size(9,9));

//模糊化以后进行阈值化,得到到对应的黑白二值化图像,二值化的阈值可以根据实际情况调整

Imgproc.threshold(blurImage,thresholdImage,210,255,Imgproc.THRESH_BINARY);

//看看二值化图像

new ImageViewer(thresholdImage, "4图").imshow();

//二值化以后的图像,条形码之间的黑白没有连接起来,就要进行形态学运算,消除缝隙,相当于小型的黑洞,选择闭运算

//因为是长条之间的缝隙,所以需要选择宽度大于长度

Mat kernel = Imgproc.getStructuringElement(MORPH_RECT,new Size(21,7));

Imgproc.morphologyEx(thresholdImage,morphImage,MORPH_CLOSE,kernel);

//看看形态学操作以后的图像

new ImageViewer(morphImage, "5图").imshow();

//现在要让条形码区域连接在一起,所以选择膨胀腐蚀,而且为了保持图形大小基本不变,应该使用相同次数的膨胀腐蚀

//先腐蚀,让其他区域的亮的地方变少最好是消除,然后膨胀回来,消除干扰,迭代次数根据实际情况选择

Imgproc.erode(morphImage,morphImage,Imgproc.getStructuringElement(MORPH_RECT,new Size(3,3)),new Point(-1,-1),4);

Imgproc.dilate(morphImage,morphImage,Imgproc.getStructuringElement(MORPH_RECT,new Size(3,3)),new Point(-1,-1),4);

//看看形态学操作以后的图像

new ImageViewer(morphImage, "6图").imshow();

List cOntours= new ArrayList();

List cOntourArea= new ArrayList();

Mat hierarchy = new Mat();

//接下来对目标轮廓进行查找,目标是为了计算图像面积

Imgproc.findContours(morphImage,contours,hierarchy,Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_SIMPLE);

System.out.println("============"+contours.size());

//计算轮廓的面积并且存放

for(int i = 0; i

{

contourArea.add(Imgproc.contourArea(contours.get(i)));

}

//找出面积最大的轮廓

Double maxValue;Point maxLoc;

Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(morphImage);

// minMaxLoc(contourArea, NULL,&maxValue,NULL,&maxLoc);

// minMaxLoc()

// Core.MinMaxLocResult

// Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(morphImage,morphImage);//Core.minMaxLoc(morphImage);

maxValue = minMaxLocResult.maxVal;

maxLoc = minMaxLocResult.maxLoc;

System.out.println("x:"+maxLoc.x+" y:"+maxLoc.y+" maxVal:"+maxValue);

//

// System.out.println("*********Start*******");

List newCOntours= new ArrayList<>();

for(MatOfPoint point : contours) {

MatOfPoint2f newPoint = new MatOfPoint2f(point.toArray());

newContours.add(newPoint);

}

/计算面积最大的轮廓的最小的外包矩形

MatOfPoint2f m2f = (MatOfPoint2f) contours.get((int)maxLoc.x);

RotatedRect minRect = minAreaRect(newContours.get((int)maxLoc.x));

//

//

//

//

//

// //为了防止找错,要检查这个矩形的偏斜角度不能超标

// //如果超标,那就是没找到

if(minRect.angle<2.0){

//找到了矩形的角度,但是这是一个旋转矩形,所以还要重新获得一个外包最小矩形

Rect myRect = boundingRect(newContours.get((int)maxLoc.x));

// //把这个矩形在源图像中画出来

rectangle(srcImage,myRect,new Scalar(0,255,255),3,LINE_AA);

// //把这个矩形在源图像中画出来

new ImageViewer(srcImage, "7图").imshow();

}



推荐阅读
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • Java编程实现邻接矩阵表示稠密图的方法及实现类介绍
    本文介绍了Java编程如何实现邻接矩阵表示稠密图的方法,通过一个名为AMWGraph.java的类来构造邻接矩阵表示的图,并提供了插入结点、插入边、获取邻接结点等功能。通过使用二维数组来表示结点之间的关系,并通过元素的值来表示权值的大小,实现了稠密图的表示和操作。对于对稠密图的表示和操作感兴趣的读者可以参考本文。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
author-avatar
胖肉肉520
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有