iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android基于OpenCV实现QR二维码检测
  • 358
分享到

Android基于OpenCV实现QR二维码检测

2024-04-02 19:04:59 358人浏览 薄情痞子
摘要

目录QR二维码QR二维码格式QR二维码结构apiQRCodeDetector类结构检测QR二维码识别QR二维码检测并识别QR二维码操作结果源码QR二维码 QR码(英语:Quick

QR二维码

QR码(英语:Quick Response Code;全称为快速响应矩阵图码)是二维码的一种,于1994年由日本DENSO WAVE公司发明。QR来自英文Quick Response的缩写,即快速反应,因为发明者希望QR码可以快速解码其内容。QR码使用四种标准化编码模式(数字、字母数字、字节(二进制)和日文(Shift_JIS))来存储数据。QR码常见于日本,为目前日本最通用的二维空间条码,在世界各国广泛运用于手机读码操作。QR码比普通一维条码具有快速读取和更大的存储资料容量,也无需要像一维条码般在扫描时需要直线对准扫描仪。因此其应用范围已经扩展到包括产品跟踪,物品识别,文档管理,库存营销等方面。【维基百科】

QR二维码格式

QR码呈正方形,常见的是黑白两色。在3个角落,印有较小,像“回”字的正方图案。这3个是帮助解码软件定位的图案,用户不需要对准,无论以任何角度扫描,资料仍然可以正确被读取。日本QR码的标准JIS X 0510在1999年1月发布,而其对应的ISO国际标准ISO/IEC18004,则在2000年6月获得批准。根据Denso Wave公司的网站资料,QR码是属于开放式的标准,QR码的规格公开,虽由Denso Wave公司持有的专利权益,但不会被运行。除了标准的QR码之外,也存在一种称为“微型QR码”的格式,是QR码标准的缩小版本,主要是为了无法处理较大型扫描的应用而设计。微型QR码同样有多种标准,最高可存储35个字符。【维基百科】

QR二维码结构

QR码最大特征为其左上,右上,左下三个大型的如同“回”字的黑白间同心方图案,为QR码识别定位标记,失去其中一个会影响识别。而呈棋盘般分布的有别与大定位标记的较小的同心方则为其校正标记,用于校正识别,版本1没有校正标记,版本2在右下方,其中心点在左下和右上定位标记的外边框的相交点,版本10开始以每个等距的方式出现在右下校正点至左下和右上定位标记的外边框的连线、左上与左下定位标记的外边框的连线、左上与右上定位标记的外边框的连线之间、这四边线上等距点对边相连线,版本10等距有1个,版本25为3个,版本40为5个。【维基百科】

API

QRCodeDetector类结构

检测QR二维码


public boolean detect(Mat img, Mat points)
  • 参数一:img,待检测是否含有QR二维码的的灰度图或者彩色(BGR)图像。
  • 参数二:points,检测到的QR二维码的最小区域四边形的4个顶点坐标集合
  • 返回值:布尔类型,true,代表检测到QR二维码;false,代表未检测到QR二维码。

public boolean detectMulti(Mat img, Mat points)
  • 参数一:img,待检测是否含有QR二维码的的灰度图或者彩色(BGR)图像。
  • 参数二:points,多个检测结果QR二维码的最小区域四边形的4个顶点坐标集合。
  • 返回值:布尔类型,true,代表检测到QR二维码;false,代表未检测到QR二维码。

识别QR二维码


public String decode(Mat img, Mat points, Mat straight_qrcode) 
  • 参数一:img,含有QR二维码的灰度图像或者彩色(BGR)图像。
  • 参数二:points,detect方法得到的points值。数据量不可为空。
  • 参数三:straight_qrcode,经过矫正和二值化的QR二维码。【可选参数】
  • 返回值:字符串类型,如果解码失败,则为空串。

public boolean decodeMulti(Mat img, Mat points, List<String> decoded_info, List<Mat> straight_qrcode)
  • 参数一:img,含有QR二维码的灰度图像或者彩色(BGR)图像。
  • 参数二:points,detect方法得到的points值。数据量不可为空。
  • 参数三:decoded_info,多个二维码的解码信息。
  • 参数四:straight_qrcode,所有检测到的二维码矫正和二值化的后的结果集合。【可选参数】
  • 返回值:布尔类型,true,代表解码成功,反之,解码失败。

检测并识别QR二维码


public String detectAndDecode(Mat img, Mat points, Mat straight_qrcode)
  • 参数一:img,含有QR二维码的灰度图像或者彩色(BGR)图像。
  • 参数二:points,检测到的QR二维码的最小区域四边形的4个顶点坐标。
  • 参数三:straight_qrcode,经过矫正和二值化的QR二维码。【可选参数】
  • 返回值:字符串类型,如果解码失败,则为空串。

public boolean detectAndDecodeMulti(Mat img, List<String> decoded_info, Mat points, List<Mat> straight_qrcode)
  • 参数一:img,含有QR二维码的灰度图像或者彩色(BGR)图像。
  • 参数二:decoded_info,多个二维码的解码信息。
  • 参数三:points,检测到的多个QR二维码的最小区域四边形的4个顶点坐标集合。【可选参数】
  • 参数四:straight_qrcode,所有检测到的二维码矫正和二值化的后的结果集合。【可选参数】
  • 返回值:字符串类型,如果解码失败,则为空串。

操作



class QRDetectActivity : AppCompatActivity() {

    private lateinit var mBinding: ActivityQrDetectBinding
    private lateinit var MQRCodeDetector: QRCodeDetector

    private var mPhotoSavePath = ""
    private lateinit var mUri: Uri
    private lateinit var mSource: Mat
    private lateinit var mGray: Mat
    private lateinit var mOperationSheet: BottomSheetDialog
    private lateinit var mSheetBinding: LayoutQrDetectOpBinding

    private lateinit var mPhotoSheet: BottomSheetDialog
    private lateinit var mPhotoOpBinding: LayoutPhotoOpBinding


    // 请求相机权限
    private val requestCameraPermission =
        reGISterForActivityResult(ActivityResultContracts.RequestPermission()) {
            if (it) {
                mPhotoSavePath =
                    cacheDir.path + File.separator + "${System.currentTimeMillis()}.png"
                mUri = MediaStoreUtils.getIntentUri(this, File(mPhotoSavePath))
                requestCamera.launch(mUri)
            } else {
                Toast.makeText(applicationContext, "无相机权限", Toast.LENGTH_SHORT).show()
            }
        }

    // 请求外部存储权限
    private val requestStoragePermission =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) {
            if (it) {
                pickImage.launch("image/*")
            } else {
                Toast.makeText(applicationContext, "无存储权限", Toast.LENGTH_SHORT).show()
            }
        }


    private val requestCamera = registerForActivityResult(ActivityResultContracts.TakePicture()) {
        if (it) {
            val bgr = ImGCodecs.imread(mPhotoSavePath, Imgcodecs.IMREAD_COLOR)
            if (bgr.empty()) {
                Toast.makeText(applicationContext, "读取拍照结果失败", Toast.LENGTH_SHORT).show()
                return@registerForActivityResult
            } else {
                Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
                Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
                mBinding.ivLena.showMat(mSource)
            }
        } else {
            Toast.makeText(applicationContext, "拍照失败", Toast.LENGTH_SHORT).show()
        }
    }

    private val pickImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
        if (it != null) {
            val filePath = MediaStoreUtils.getMediaPath(this, it)
            if (filePath.isNullOrEmpty()) {
                Toast.makeText(applicationContext, "读取图片失败", Toast.LENGTH_SHORT).show()
                return@registerForActivityResult
            }
            val bgr = Imgcodecs.imread(filePath, Imgcodecs.IMREAD_COLOR)
            if (bgr.empty()) {
                Toast.makeText(applicationContext, "读取图片失败", Toast.LENGTH_SHORT).show()
                return@registerForActivityResult
            } else {
                Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
                Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
                mBinding.ivLena.showMat(mSource)
            }
        } else {
            Toast.makeText(applicationContext, "选图失败", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_qr_detect)
        mQRCodeDetector = QRCodeDetector()
        mSource = Mat()
        mGray = Mat()
        val bgr = Utils.loadResource(this, R.drawable.qrcode)
        Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
        Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
        mBinding.ivLena.showMat(mSource)
        createDialog()
    }

    private fun createDialog() {
        mOperationSheet = BottomSheetDialog(this)
        mSheetBinding = LayoutQrDetectOpBinding.inflate(layoutInflater, null, false)
        mOperationSheet.setContentView(mSheetBinding.root)
        mSheetBinding.tvDetect.setOnClickListener {
            mOperationSheet.dismiss()
            doDetect()
        }
        mSheetBinding.tvDecode.setOnClickListener {
            mOperationSheet.dismiss()
            doDecode()
        }

        mPhotoSheet = BottomSheetDialog(this)
        mPhotoOpBinding = LayoutPhotoOpBinding.inflate(layoutInflater, null, false)
        mPhotoSheet.setContentView(mPhotoOpBinding.root)
        mPhotoOpBinding.tvCamera.setOnClickListener {
            mPhotoSheet.dismiss()
            requestCameraPermission.launch(
                Manifest.permission.CAMERA
            )
        }
        mPhotoOpBinding.tvPhoto.setOnClickListener {
            mPhotoSheet.dismiss()
            requestStoragePermission.launch(
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )

        }
    }

    private fun doDetect() {
        val points = Mat()
        val isHasQr = mQRCodeDetector.detect(mSource, points)
        if (isHasQr) {
            val pointArr = FloatArray(8)
            points.get(0, 0, pointArr)
            Log.d(App.TAG, pointArr.toList().toString())
            val tmp = mSource.clone()
            for (i in pointArr.indices step 2) {
                val start = Point(pointArr[i % 8].toDouble(), pointArr[(i + 1) % 8].toDouble())
                val end = Point(pointArr[(i + 2) % 8].toDouble(), pointArr[(i + 3) % 8].toDouble())
                Imgproc.line(tmp, start, end, Scalar(255.0, 0.0, 0.0), 8, Imgproc.LINE_8)
            }
            mBinding.ivResult.showMat(tmp)
            tmp.release()
        }
    }

    private fun doDecode() {
        val points = Mat()
        val isHasQr = mQRCodeDetector.detect(mGray, points)
        if (isHasQr) {
            val result = mQRCodeDetector.decode(mGray, points)
            if (result.isEmpty()) {
                Toast.makeText(applicationContext, "无法解码", Toast.LENGTH_SHORT).show()
            } else {
                Snackbar.make(mBinding.root, "解码结果:$result", 3000).show()
            }
            Log.d(App.TAG, result)
        } else {
            Toast.makeText(applicationContext, "未检测到QRCode", Toast.LENGTH_SHORT).show()
        }
    }

    private fun selectMedia() {
        if (this::mPhotoSheet.isInitialized) {
            mPhotoSheet.show()
        }
    }

    private fun selectOps() {
        if (this::mOperationSheet.isInitialized) {
            mOperationSheet.show()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_qr_detect, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_pick_photo -> selectMedia()
            R.id.menu_qr_ops -> selectOps()
        }
        return true
    }

    override fun onDestroy() {
        mSource.release()
        mGray.release()
        super.onDestroy()
    }
}

结果

源码

GitHub.com/onlyloveyd/…

以上就是Android基于OpenCV实现QR二维码检测的详细内容,更多关于Android OpenCV实现QR二维码检测的资料请关注编程网其它相关文章!

--结束END--

本文标题: Android基于OpenCV实现QR二维码检测

本文链接: https://www.lsjlt.com/news/128466.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android基于OpenCV实现QR二维码检测
    目录QR二维码QR二维码格式QR二维码结构APIQRCodeDetector类结构检测QR二维码识别QR二维码检测并识别QR二维码操作结果源码QR二维码 QR码(英语:Quick...
    99+
    2024-04-02
  • C++ OpenCV实现二维码检测功能
    目录前言一、二维码检测二、二维码识别三、二维码绘制四、源码总结前言 本文将使用OpenCV C++ 进行二维码检测。 一、二维码检测 首先我们要先将图像进行预处理,通过灰度、滤波、...
    99+
    2024-04-02
  • Android基于OpenCV实现Harris角点检测
    目录什么是角点? 为什么要检测角点? Harris角点检测 API操作效果 源码 什么是角点? 角点就是极值点,即在某方面属性特别突出的点。当然,你可以自己定义角点的属性(设置特定...
    99+
    2024-04-02
  • Android基于OpenCV实现霍夫直线检测
    目录霍夫直线检测点和线的对偶性极坐标参数方程API操作效果霍夫直线检测 点和线的对偶性 图像空间中的点,对应霍夫空间中的直线 图像空间中的直线,对应霍夫空间中的...
    99+
    2024-04-02
  • 如何实现基于opencv的行人检测
    这篇文章主要为大家展示了“如何实现基于opencv的行人检测”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何实现基于opencv的行人检测”这篇文章吧。基于方向梯度直方图(HOG)/线性支持向...
    99+
    2023-06-22
  • OpenCV基于ORB算法实现角点检测
    本文实例为大家分享了OpenCV基于ORB算法实现角点检测的具体代码,供大家参考,具体内容如下 ORB算法是FAST算法和BRIEF算法的结合,ORB可以用来对图像中的关键点快速创建...
    99+
    2024-04-02
  • python基于Opencv实现人脸口罩检测
    一、开发环境 python 3.6.6 opencv-python 4.5.1 二、设计要求 1、使用opencv-python对人脸口罩进行检测 三、设计原理 设计流程图如图3-1...
    99+
    2024-04-02
  • 基于barcodescanner实现Android二维码扫描功能
    二维码扫描现在成为一种非常常见的APP基础功能,附录1是我曾经用过的二维码/条形码扫描开源项目,但是附录1的项目集成和二次定制比较繁琐和麻烦,因此可以发现不少人基于ZXing做了二次的开发,并贡献出这些项目,发到github上,其中barc...
    99+
    2023-05-30
    android 二维码 barcodescanner
  • 基于Python OpenCV和 dlib实现眨眼检测
    目录了解“眼睛纵横比”(EAR)使用面部标志和 OpenCV 检测眨眼眨眼检测结果总结今天,我们使用面部标记和 OpenCV 检测视频流中的眨眼次数。 为了构建我们的眨眼检测器,我们...
    99+
    2024-04-02
  • 基于Mediapipe+Opencv实现手势检测功能
    目录一、前言二、环境配置软件:环境:三、全部源码MediapipeHandTracking.py程序结构:MediapipeHandTracking.py源码与注释四、环境配置1、在...
    99+
    2024-04-02
  • opencv案例03 -基于OpenCV实现二维码生成,发现,定位,识别
    1.二维码的生成 废话不多说,直接上代码 # 生成二维码import qrcode# 二维码包含的示例数据data = "B0018"# 生成的二维码图片名称filename = "qrcode.png"# 生成二维码img = qrcod...
    99+
    2023-08-30
    opencv 人工智能 计算机视觉
  • 基于Mediapipe+Opencv如何实现手势检测功能
    今天给大家介绍一下基于Mediapipe+Opencv如何实现手势检测功能。,文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。一、前言基于Mediapipe+Op...
    99+
    2023-06-26
  • 基于深度学习和OpenCV实现目标检测
    目录使用深度学习和OpenCV进行目标检测MobileNets:高效(深度)神经网络使用OpenCV进行基于深度学习的对象检测使用OpenCV检测视频使用深度学习和 OpenCV 进...
    99+
    2024-04-02
  • 如何基于OpenCV&Python实现霍夫变换圆形检测
    简述 基于python使用opencv实现在一张图片中检测出圆形,并且根据坐标和半径标记出圆。不涉及理论,只讲应用。 霍夫变换检测圆形的原理 其实检测圆形和检测直线的原理差别不大...
    99+
    2024-04-02
  • python目标检测基于opencv实现目标追踪示例
    目录主要代码信息封装类更新utilspython-opencv3.0新增了一些比较有用的追踪器算法,这里根据官网示例写了一个追踪器类 程序只能运行在安装有opencv3.0以上版本和...
    99+
    2024-04-02
  • QR-Code二维码如何利用zxing库实现生成
    QR-Code二维码如何利用zxing库实现生成?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。详解使用zxing库生成QR-Code二维码首先是引入zxing库,我是使用mav...
    99+
    2023-05-31
    zxing库 qr-code 二维码
  • Python机器视觉怎么实现基于OpenCV的手势检测
    本篇内容介绍了“Python机器视觉怎么实现基于OpenCV的手势检测”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1 简介今天学长向大家介...
    99+
    2023-06-22
  • opencv 案例05-基于二值图像分析(简单缺陷检测)
    缺陷检测,分为两个部分,一个部分是提取指定的轮廓,第二个部分通过对比实现划痕检测与缺角检测。本次主要搞定第一部分,学会观察图像与提取图像ROI对象轮廓外接矩形与轮廓。 下面是基于二值图像分析的大致流程 读取图像将图像转换为灰度图,并对其进行...
    99+
    2023-08-30
    opencv 人工智能 计算机视觉 目标检测
  • 基于java服务端实现二维码扫描
    基于java服务端识别二维码得方法 在Java中,可以使用第三方库来识别二维码内容。一个常用的库是ZXing(Zebra Crossing),它提供了强大的二维码处理功能。 首先,确保已将ZXing库...
    99+
    2023-09-22
    java 二维码 识别 扫描
  • Android基于OpenCV实现图像修复
    目录图像修复API操作效果源码图像修复 实际应用中,图像常常容易受损,如存在污渍的镜头、旧照片的划痕、人为的涂画(比如马赛克),亦或是图像本身的损坏。将受到损坏的图像尽可能还原成原...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作