Android使用OpenCV 4.5.0实现扑克牌识别(源码分享)

一、显示效果展示

二、OpenCV 4.5.0

OpenCV 4.5.0是OpenCV(Open Source Computer Vision Library,开源计算机视觉库)的一个重要更新版本,该版本在多个方面进行了优化和新增了多项功能。

三、ONNX模型

ONNX(Open Neural Network Exchange)模型是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。它允许不同的深度学习框架(如PyTorch、TensorFlow、MXNet等)之间交换和共享模型,使得模型可以在不同平台和工具上进行部署和推理。

四、OpenCV加载onnx模型进行前向推理实现识别扑克牌识别


    //统计预测的结果
    private int[] number_class=new int[54];
    public Bitmap detection(Bitmap bp){
        Canvas can=new Canvas();
        Paint p=new Paint();
        android.graphics.Bitmap.Config bitmapConfig = bp.getConfig();
        bp = bp.copy(bitmapConfig, true);
        can=new Canvas(bp);
        p.setAntiAlias(true);
        //不填充,默认填充
        p.setStyle(Paint.Style.STROKE);
        //设置线条宽度
        p.setStrokeWidth(5);
        //设置颜色
        p.setColor(0xFF33FFFF);
        p.setTextAlign(Paint.Align.LEFT);
        p.setTextSize(50);

        Mat blob = Dnn.blobFromImage(src, IN_SCALE_FACTOR,
                new Size(IN_WIDTH, IN_HEIGHT),
                new Scalar(MEAN_VAL, MEAN_VAL, MEAN_VAL), false);
        net.setInput(blob);
        blob.release();

        //获取输出层的名字
        List<String> outnames=net.getUnconnectedOutLayersNames();
//        Log.i("aa",String.valueOf(outnames));
        //创建输出矩阵集合
        List<Mat> detections = new ArrayList<Mat>();
        net.forward(detections,outnames);
        //获取输出的盒子和置信度
        Mat scores=detections.get(0);
        Mat boxes= detections.get(1);
        scores= scores.reshape(1,3000).colRange(1,55);
        boxes= boxes.reshape(1,3000);
        Size ss=scores.size();
//        Log.i("aa",String.valueOf(scores));
//        Log.i("aa",String.valueOf(boxes));

        List<Rect2d> rect2dList=new ArrayList<>();//box信息
        List<Float> confList=new ArrayList<>();//置信度
        List<Integer> objIndexList=new ArrayList<>();//对象类别索引


        for(int i=0; i<scores.rows();i++){
            Mat one_row=scores.rowRange(i,i+1);
            Core.MinMaxLocResult max_index=Core.minMaxLoc(one_row);
            double max_value=max_index.maxVal;
            Point location=max_index.maxLoc;
            if(max_value>0.4){

                confList.add((float) max_value);
                objIndexList.add((int)location.x);

                Mat box_one=boxes.rowRange(i,i+1);
                float[] aa=new float[4];
                box_one.get(0,0,aa);

                double x1=aa[0];
                double y1=aa[1];
                double x2=aa[2];
                double y2=aa[3];
                rect2dList.add(new Rect2d(x1,y1,x2,y2));

            }

        }

        //去重
        //去重后的索引值
        MatOfInt index=new MatOfInt();
        //转换box的结果集
        MatOfRect2d boxe=new MatOfRect2d(rect2dList.toArray(new Rect2d[0]));
        //转换置信度结果集
        float[] confArr=new float[confList.size()];
        for(int j=0;j<confList.size();j++){
            confArr[j]=confList.get(j);
        }
        MatOfFloat con=new MatOfFloat(confArr);
        //使用nms去重
        Dnn.NMSBoxes(boxe,con,0.4f,0.45f,index);
        if (index.empty()){
            return bp;
        }
        //画框
        int[] ints=index.toArray();

        for(int x:ints){
//            Log.i("aa",String.valueOf(x));

            double[] aa=new double[4];
            boxe.get(x,0,aa);
            //Log.i("aa",String.valueOf(aa[0]));
            //Imgproc.rectangle(src,new Point(aa[0]*src.width(),aa[1]*src.height()-70),new Point(aa[2]*src.width()+200,aa[1]*src.height()),new Scalar(255,255,255),-1);
            //Imgproc.rectangle(src,new Point(aa[0]*src.width(),aa[1]*src.height()),new Point(aa[2]*src.width(),aa[3]*src.height()),new Scalar(255,255,0),10);

            //Imgproc.putText(src,""+classNames[objIndexList.get(x)]+":"+confList.get(x),new Point(aa[0]*src.width(),aa[1]*src.height()),Imgproc.FONT_HERSHEY_SIMPLEX, 3, new Scalar(0, 0, 0));
            //画框
            can.drawRect((float) aa[0]*src.width(),(float) aa[1]*src.height(),(float)aa[2]*src.width(),(float)aa[3]*src.height(),p);
            //绘制填充框
            p.setStyle(Paint.Style.FILL);
            p.setColor(0xFFFFCC00);
            can.drawRect((float) aa[0]*src.width(),(float) aa[1]*src.height()-60,(float)aa[2]*src.width()+150,(float)aa[1]*src.height(),p);
            //写字
            p.setColor(0xFFFF0000);
            can.drawText(classNames[objIndexList.get(x)]+": "+String.format("%.3f", confList.get(x)),(float)aa[0]*src.width(),(float) aa[1]*src.height()-10,p);
            p.setStyle(Paint.Style.STROKE);
            p.setColor(0xFF33FFFF);

            //统计类别信息
            number_class[objIndexList.get(x)]+=1;
        }

五、完整源码下载:

Card.zip: https://url83.ctfile.com/f/45573183-1373015108-43a4dd?p=7526 (访问密码: 7526)
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/883824.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIP——HCIA回顾

第一章.HCIA复习 引入场景 其实IA我们主要学习的无非就是数据包在网络中传递的基本过程&#xff0c;我们设计一个场景&#xff0c;通过回顾web页面的请求过程&#xff0c;将IA学过的基本网络工作原理来串一遍。 (在本例中&#xff0c;ISP网络为学校提供了DNS服务&#xff0c;…

学习C++的第七天!

1.虚函数是在基类中用 virtual 关键字声明的函数&#xff0c;可以在派生类中被重写。纯虚函数是在虚函数的基础上&#xff0c;在基类中被初始化为 0 的函数&#xff0c;含有纯虚函数的类是抽象类&#xff0c;不能被实例化。 2.如果基类的析构函数不是虚函数&#xff0c;当通过…

今年双十一不被割韭菜!要买就要高品质好物~总结五款好物推荐!

双十一购物盛宴如约而至&#xff0c;面对琳琅满目的商品是否感到选择有些迷茫&#xff1f;别担心&#xff0c;专为选择困难症的朋友们准备了一份精选好物清单&#xff0c;旨在丰富您的数字生活体验。无需犹豫&#xff0c;这份指南将助您轻松锁定心仪之选&#xff0c;把握时机&a…

ER-Nerf 数字人训练视频的准备

数字人训练视频的准备 分辨率帧率时长背景处理推荐工具举个例子 分辨率 布局Value横屏1920x1080竖屏1080x1920 帧率 25fps 时长 大于1分钟&#xff08;60秒&#xff09;的视频 解释&#xff1a; 1、数字人采用循环的播放模式&#xff0c;时长越长会降低出现前后拼接的现象…

票据直联“票通全球”,全球司库热点服务之三——在线开票

在当今全球化的经济浪潮中&#xff0c;企业的财务管理面临着日益复杂的挑战。如何高效、安全地进行资金结算和票据管控&#xff0c;成为企业发展的关键问题。而全球司库票据直联服务的出现&#xff0c;为企业提供了一种创新的解决方案&#xff0c;尤其是在线开票方面&#xff0…

语言模型发展史

四个阶段 第一阶段&#xff1a;基于规则和统计的语言模型 由人工设计特征并使用统计方法对固定长度的文本窗口序列进行建模分析&#xff0c;这种建模方式也被称为N-gram语言模型。 优点&#xff1a; 1&#xff09;采用极大似然估计, 参数易训练 2&#xff09;完全包含了前n-…

Python和C++及MATLAB距离相关性生物医学样本统计量算法及数据科学

&#x1f3af;要点 统计观测值之间距离计算代谢组学和脂质组学分析相关距离矩阵计算卡方检验偏差校正快速计算距离协方差算法大规模生物系统分析距离矩阵相关性测试石油勘探统计学关系 Python距离矩阵 在数学、计算机科学&#xff0c;尤其是图论中&#xff0c;距离矩阵是一…

mysql 内存被打满记录

一&#xff1a;早上收到报警&#xff1a;提示&#xff1a;您的云数据库RDS的1个实例因存储空间满将被锁定&#xff0c;请关注实例的存储空间使用情况&#xff0c;可通过存储扩容或空间清理解除锁定。后续查看错误日志如下&#xff1a;磁盘没有空间了 没有多余的空间写binlog和…

随记——机器学习

前言 本来有个500块钱的单子&#xff0c;用机器学习做一个不知道什么鸟的识别&#xff0c;正好有数据集&#xff0c;跑个小项目&#xff0c;过一下机器学习图像识别的流程&#xff0c;用很短的时间记录下来..... 一、数据预处理 将数据集分为训练集和测试集&#xff0c;直接…

onload_tcpdump命令抓包报错Onload stack [7,] already has tcpdump process

最近碰到Onload 不支持同时运行多个 tcpdump 进程的报错&#xff0c;实际上使用了ps查询当时系统中并没有tcpdump相关进程存在。需要重启服务器本机使用onload加速的相关进程后才能使用onload_tcpdump正常抓包&#xff0c;很奇怪&#xff0c;之前确实没遇到这样的问题&#xff…

李宏毅机器学习2023-HW10-Adversarial Attack

文章目录 TaskBaselineFGSM (Fast Gradient Sign Method (FGSM)I-FGSM(Iterative Fast Gradient Sign Method)MI-FGSM(Momentum Iterative Fast Gradient Sign Method)M-DI2-FGSM(Diverse Input Momentum Iterative Fast Gradient Sign Method) Reportfgsm attackJepg Compress…

【ADC】ΔΣ ADC 中数字滤波器的延迟以及 SAR ADC 与 ΔΣ ADC 的差异对比总结

本文学习于TI 高精度实验室课程&#xff0c;深入探讨 delta-sigma 转换器中使用的数字滤波器。具体来说&#xff0c;本文将重点介绍数字滤波器如何引入延迟&#xff0c;因为这是 SAR 和 delta-sigma ADC 之间的显著差异。 文章目录 一、低延迟数字滤波器二、高延迟数字滤波器三…

探索EasyCVR视频融合平台:在视频编解码与转码领域的灵活性优势

随着视频监控技术的飞速发展&#xff0c;各类应用场景对视频数据的处理需求日益复杂多样。从公共安全到智慧城市&#xff0c;再到工业监控&#xff0c;高效、灵活的视频处理能力成为衡量视频融合平台性能的重要标准。在众多解决方案中&#xff0c;EasyCVR视频融合平台凭借其在视…

大规模预训练语言模型的参数高效微调

人工智能咨询培训老师叶梓 转载标明出处 大规模预训练语言模型&#xff08;PLMs&#xff09;在特定下游任务上的微调和存储成本极高&#xff0c;这限制了它们在实际应用中的可行性。为了解决这一问题&#xff0c;来自清华大学和北京人工智能研究院的研究团队探索了一种优化模型…

基础漏洞——SSRF

目录 一.原理 二.引起ssrf的函数 三.这些函数具体作用 &#xff08;1&#xff09;File_get_content() &#xff08;2&#xff09;Fsockopen() &#xff08;3&#xff09;Curl_exec() 四.常见的业务场景&#xff08;可能出现的漏洞的地方&#xff0c;漏洞挖掘&#xff09…

展锐平台的手机camera 系统isptool 架构

展锐平台的isptool 主要用于支持展锐各代芯片isp的各效果模块快速tuning和参数生成打包。 具体需要&#xff1a; 一、工具段能在线实时预览到调试sensor经过isp 处理后的图像&#xff0c;也就是各模块的参数在当下实时生效&#xff0c;通过工具能在PC 上在线观看到修改的效果。…

【理解 Java 中的 for 循环】

理解 Java 中的 for 循环 for 循环是 Java 中用于迭代的常用控制结构&#xff0c;它可以帮助我们重复执行某段代码&#xff0c;直到满足特定条件。本文将介绍 for 循环的基本语法、执行流程、注意事项及一些练习。 基本语法 for 循环的基本语法如下&#xff1a; for (循环变…

FBX福币连续2天破万亿,沪指重回3000点,后续怎么走?

查查配分析今日,A股继续强势上攻。有关#A股重回3000点#、#A股成交额连续2天破万亿#的讨论迅速登上微博热搜。 FBX福币凭借用户友好的界面和对透明度的承诺,迅速在加密货币市场中崭露头角,成为广大用户信赖的平台。 白马蓝筹股领涨市场,上证50指数劲升逾4.69%,创近4个月来新高,…

Java语法-类和对象之继承与多态(中)

1. 继承 为什么要继承? 从生物学角度来说,继承就是把父辈的基因遗传给子代,然后子代再在细胞分裂的途中产生变异,生成比父辈更加适应环境的物种.其中很重要的就是继承给子代的基因(父类的方法和属性)和子代在父辈的基础上产生的变异(方法的重写). 比如猫和狗都是哺乳动物,是在…

了解独享IP的概念及其独特优势

在网络世界中&#xff0c;IP地址是用来识别和定位设备的标识符。独享IP是一种服务模式。使用代理服务器时&#xff0c;用户拥有一个不与其他用户共享的专用独立IP地址。与共享IP相比&#xff0c;独享IP为用户提供了更高的独立性和隐私保护。下面详细介绍独享IP的定义、工作原理…