java 图片中的二维码定位

您所在的位置:网站首页 怎样识别微博图中二维码 java 图片中的二维码定位

java 图片中的二维码定位

2024-07-16 13:46:26| 来源: 网络整理| 查看: 265

java 图片中的二维码定位

使用技术:opencv 3.4.14 执行下载安装

import com.google.zxing.*; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.HybridBinarizer; import org.opencv.core.*; import org.opencv.core.Point; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.QRCodeDetector; import org.opencv.utils.Converters; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.util.*; import java.util.List; /** * 参考:https://www.cnblogs.com/huacanfly/p/9908408.html * 参考:https://blog.csdn.net/StrangeSir/article/details/93143177 * 参考:https://opencv.org/releases/ */ public class OpenCVQrCodePosition { private boolean isDebug = true; static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } // 获取二维码图片位置信息 public Point[] getPosition(String imgUrl){ Mat src = Imgcodecs.imread(imgUrl ,1); Mat src_gray = new Mat(); List contours = new ArrayList(); //彩色图转灰度图 Imgproc.cvtColor(src ,src_gray ,Imgproc.COLOR_RGB2GRAY); //对图像进行平滑处理 Imgproc.GaussianBlur(src_gray, src_gray, new Size(3,3), 0); this.printImg("1-1.jpg", src_gray); Imgproc.Canny(src_gray,src_gray,112,255); this.printImg("1-2.jpg", src_gray); Mat hierarchy = new Mat(); // 寻找轮廓 Imgproc.findContours(src_gray ,contours ,hierarchy ,Imgproc.RETR_TREE ,Imgproc.CHAIN_APPROX_NONE); List markContours = this.markContour(src_gray, contours, hierarchy); markContours = this.filterByAngle(markContours); Point[] points = this.centerCals(markContours); if(points != null){ this.cutRect(src, points, 12); } return points; } // 裁剪指定区域 public BufferedImage cutRect(Mat src,Point[] points, int offset){ if(points == null || points.length // 二维码有三个角轮廓,少于三个的无法定位放弃,多余三个的循环裁剪出来 if (markContours.size() for (int i=0; i for (int k=j+1;k return threePointList; }else{ threePointList.clear(); } } } } } return null; } // 计算三个点是否符合 90,45,45 private boolean capture(List contours){ Point[] pointthree = this.centerCals(contours); double angle1 = this.angle(pointthree[1], pointthree[0], pointthree[2]); double angle2 = this.angle(pointthree[0], pointthree[1], pointthree[2]); double angle3 = this.angle(pointthree[1], pointthree[2], pointthree[0]); System.out.println("angle1:"+angle1+",angle2:"+angle2+",angle3:"+angle3); if (Double.isNaN(angle1) || Double.isNaN(angle2) || Double.isNaN(angle3)){ return false; } // 最大角度和最小角度 double maxAngle = Math.max(angle3,Math.max(angle1,angle2)); double minAngle = Math.min(angle3,Math.min(angle1,angle2)); if (maxAngle95 || minAngle 50){ /**二维码为直角,最大角过大或者过小都判断为不是二维码*/ return false; } return true; } // 计算夹角 private double angle(Point p1, Point p2, Point p3){ double[] ca = new double[2]; double[] cb = new double[2]; ca[0] = p1.x - p2.x; ca[1] = p1.y - p2.y; cb[0] = p3.x - p2.x; cb[1] = p3.y - p2.y; return 180/3.1415*Math.acos((ca[0]*cb[0]+ca[1]*cb[1])/(Math.sqrt(ca[0]*ca[0]+ca[1]*ca[1])*Math.sqrt(cb[0]*cb[0]+cb[1]*cb[1]))); } // 转换为点 private Point[] centerCals(List matOfPoint){ if(matOfPoint == null || matOfPoint.size() == 0){ return null; } Point[] pointthree = new Point[matOfPoint.size()]; for(int i=0; i double centerx=0,centery=0; MatOfPoint2f mat2f = new MatOfPoint2f( matOfPoint.toArray() ); RotatedRect rect = Imgproc.minAreaRect( mat2f ); Point vertices[] = new Point[4]; rect.points(vertices); centerx = ((vertices[0].x + vertices[1].x)/2 + (vertices[2].x + vertices[3].x)/2)/2; centery = ((vertices[0].y + vertices[1].y)/2 + (vertices[2].y + vertices[3].y)/2)/2; Point point= new Point(centerx,centery); return point; } // 寻找二维码轮廓点 private List markContour(Mat src_gray, List contours, Mat hierarchy) { List markContours = new ArrayList(); for (int i = 0; i //计算层数,二维码角框有五层轮廓(有说六层),这里不计自己这一层,有4个以上子轮廓则标记这一点 double[] ds = hierarchy.get(0, i); if (ds != null && ds.length>3){ int count =0; if (ds[3] == -1){/**最外层轮廓排除*/ continue; } //计算所有子轮廓数量 while ((int) ds[2] !=-1){ ++count; ds = hierarchy.get(0 ,(int) ds[2]); } if (count >= 4){ markContours.add(contours.get(i)); } } } } return markContours; } // 测试打印图片 private void printImg(String name, Mat img){ if(isDebug) { String path = String.format("%s/%s", System.getProperty("user.dir"), name); System.out.println("out:" + path); Imgcodecs.imwrite(path, img); } } /** * Mat转换成BufferedImage * * @param matrix 要转换的Mat * @param fileExtension 格式为 ".jpg", ".png", etc * @return */ public static BufferedImage mat2BufImg(Mat matrix, String fileExtension) { // convert the matrix into a matrix of bytes appropriate for // this file extension MatOfByte mob = new MatOfByte(); Imgcodecs.imencode(fileExtension, matrix, mob); // convert the "matrix of bytes" into a byte array byte[] byteArray = mob.toArray(); BufferedImage bufImage = null; try { InputStream in = new ByteArrayInputStream(byteArray); bufImage = ImageIO.read(in); } catch (Exception e) { e.printStackTrace(); } return bufImage; } /** * BufferedImage转换成Mat * * @param original * 要转换的BufferedImage * @param imgType * bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR * @param matType * 转换成mat的type 如 CvType.CV_8UC3 */ public static Mat bufImg2Mat (BufferedImage original, int imgType, int matType) { if (original == null) { throw new IllegalArgumentException("original == null"); } // Don't convert if it already has correct type if (original.getType() != imgType) { // Create a buffered image BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType); // Draw the image onto the new buffer Graphics2D g = image.createGraphics(); try { g.setComposite(AlphaComposite.Src); g.drawImage(original, 0, 0, null); } finally { g.dispose(); } } DataBufferByte dbi = (DataBufferByte) original.getRaster().getDataBuffer(); byte[] pixels = dbi.getData(); Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType); mat.put(0, 0, pixels); return mat; } /** * 解析读取二维码 * 先使用ZXING二维码识别,若失败,使用OPENCV自带的二维码识别 * 个人测试,两者的识别率差不多,都不尽人意,但一起使用还是可以略微提高一点识别率,毕竟实现算法不一样 * 若还要其它的识别,类似Zbar,都可以集成进来 * * @param qrCodePath 二维码图片路径 * @return 成功返回二维码识别结果,失败返回null * @throws Exception */ public static String decodeQRcode(String qrCodePath){ String qrCodeText = null; try { BufferedImage image = ImageIO.read(new File(qrCodePath)); LuminanceSource source = new BufferedImageLuminanceSource(image); Binarizer binarizer = new HybridBinarizer(source); BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); Map hints = new HashMap(); hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); Result result = new MultiFormatReader().decode(binaryBitmap, hints); qrCodeText = result.getText(); } catch (Exception e) { qrCodeText = new QRCodeDetector().detectAndDecode(Imgcodecs.imread(qrCodePath, 1)); } return qrCodeText; } public static void main(String[] args) { String img = "C:\\Users\\jonk\\Desktop\\2.png"; Point[] points = new OpenCVQrCodePosition().getPosition(img); if(points == null) { System.out.println("可能不包含二维码:"+img); return; } for (int i = 0; i


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭