【图文详解】Android Studio(新版本) 配置OpenCV库,解决出现的各种问题

前言

写这篇文章的目的就是记录自己在配置OpenCV库时遇到的问题。在网上查找相关资料时,发现很多Android Studio都是老版本,并且出现的问题都不能被解决。自己在配置过程中出现的问题都进行记录下来并一一解决。

新建项目

点击 New Project

选择界面

配置相关参数

创建成功

确保创建成功(真机测试)

前提:手机要打开开发者模式启用USB调试

手机界面出现 Hello World! 即可成功。

导入 OpenCV

先要去OpenCV库官网下载OpenCVAndroid

https://opencv.org/releases/

在这里使用 opencv-4.7.0-android-sdk

解压的OpenCV文件夹

点击file->new->Import Module选择解压之后的opencv-android-sdk文件夹中的SDk文件夹,并将:sdk修改为:opencv

等待OpenCV库加载,需要等一会时间

加载好后就会出现下面的错误信息

解决出现的问题1

build.gradleopencv

修改版本

这里的版本要与build.gradle(app)的一致

修改后的内容

注释内容

apply plugin: 'kotlin-android' 进行注释

添加 namespace

namespace "org.opencv"

settings.gradleproject

1 [settings.gradle.ktsOpenCV]里面的内容复制到2 [settings.gradleOpenCV]里面

settings.gradle.ktsOpenCV

settings.gradleOpenCV

注意:在末尾新添加了一行 include(":opencv")

编译代码

现在就没有错误信息了

手机验证

正常显示

应用 OpenCV 库到 APP

点击file->project structure ->Dependencies->app->3 Module Dependency然后给opencv打上对勾,应用即可

编译代码并应用到APP上会出现下述问题

编译时是没有问题的

导出到APP上出现问题

解决出现的问题2

OpenCVEngineInterface

发现找不到这个类 import org.opencv.engine.OpenCVEngineInterface;

因为SDK 里面提供的是aidl文件路径和Android 默认的不同,但是这个需要新建一个路径 aidl/org/opencv/engine。然后把原SDK路径org.opencv.engine包下的aidl文件拷贝到前面你新建的包

build.gradle:opencv

在向build.gradle:opencv中添加下述代码

Plain Text
buildFeatures {
     aidl true
 }

导出到APP上出现下述问题

gradle.properties

gradle.properties中添加下述代码

Plain Text
android.defaults.buildfeatures.buildconfig=true

再次编译并导出到APP上,这次就没有出现任何问题

实战

图片转黑白

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_marginTop="30dp"
        android:layout_height="300dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="250dp"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_load"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="加载图片"
            android:textSize="25sp"/>
        <Button
            android:id="@+id/btn_gray"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="灰度化"
            android:textSize="25sp"/>
    </LinearLayout>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ImageView img;
    private Button btn_load, btn_gray;
    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        img = findViewById(R.id.img);
        btn_load = findViewById(R.id.btn_load);
        btn_gray = findViewById(R.id.btn_gray);

        btn_load.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loadImg();
            }
        });

        btn_gray.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                doChgGray();
            }
        });
    }

    private void loadImg(){
        Intent intent = new Intent();
        intent.setType("image/*");

        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent,1);
    }

    private void doChgGray(){
        if (bitmap==null){
            return;
        }
        Bitmap bit = bitmap.copy(Bitmap.Config.ARGB_8888,false);
        Mat src = new Mat(bit.getHeight(), bit.getWidth(), CvType.CV_8UC(3));
        Utils.bitmapToMat(bit,src);
        Imgproc.cvtColor(src,src,Imgproc.COLOR_BGR2GRAY);
        Utils.matToBitmap(src,bitmap);
        Message message = new Message();
        message.what = 1;
        handler.sendMessage(message);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        //用户操作完成,结果返回码是-1
        if (resultCode==RESULT_OK){
            Uri uri = data.getData();
            Log.e("uri",uri.toString());
            ContentResolver cr = this.getContentResolver();
            try {
                bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
                img.setImageBitmap(bitmap);
            }catch(FileNotFoundException ex){
                Log.e("Exception",ex.getMessage(),ex);
            }
        }else{
            //操作错误,或没有选择图片
            Log.i("MainActivity", "操作错误");
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!OpenCVLoader.initDebug()){
            Log.i("cv","未找到内部的opencv库,使用OpenCV Manager进行初始化");
        }else {
            Log.i("cv","发现了内置的opencv库,使用它来进行操作");
        }
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            switch (msg.what){
                case 1:
                    img.setImageBitmap(bitmap);
                    break;
            }
        }
    };
}

手机效果

结语

 欢迎关注我的公众号:@AI算法与电子竞赛    

硬性的标准其实限制不了无限可能的我们,所以啊!少年们加油吧!

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

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

相关文章

STM32F4X SDIO(九) 例程讲解-SD卡擦除、读写

STM32F4X SDIO &#xff08;九&#xff09; 例程讲解-SD卡擦除、读写 例程讲解-SD卡擦除、读写SD卡擦除CMD32:ERASE_WR_BLK_START命令发送命令响应 CMD33:ERASE_WR_BLK_END命令发送命令响应CMD38:ERASE命令响应 CMD13:SD_CMD_SEND_STATUS命令发送命令回应 SD卡读数据CMD16:SET_…

【LeetCode】挑战100天 Day10(热题+面试经典150题)

【LeetCode】挑战100天 Day10&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-122.1 题目2.2 题解 三、面试经典 150 题-123.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

matplotlib 设置标签和图例

常用标签 xlabel&#xff1a;x轴标签名称。 ylabel&#xff1a;y轴标签名称。 title&#xff1a;图像标题。 设置x和y轴的刻度&#xff1a;xticks和yticks。 nums np.arange(0, 1.3, 0.01)# 设置标题 plt.title("title") # 设置横坐标信息 plt.xlabel("x-…

复杂度计算实例

1.常见时间复杂度计算举例 实例1 实例1基本操作执行了2N10次&#xff0c;通过推导大O阶方法知道&#xff0c;时间复杂度为 O(N) 实例2 实例2基本操作执行了MN次&#xff0c;有两个未知数M和N&#xff0c;时间复杂度为 O(NM) 实例3 实例3基本操作执行了100次&#xff0c;通过…

C++学习笔记(二):C++是如何运行的

C是如何运行的 include 预处理语句&#xff0c;在编译前就会被处理。 main函数 程序入口。 #include <iostream>int main() {std::cout << "Hello World!" << std::endl;std::cin.get();return 0; }Visual Studio 解决方案平台指的是编译的代码的…

探索微信小程序框架的精华——高质量的优秀选择

目录 引言&#xff1a; 1. 框架性能 2. 开发者工具支持 3. 文档和社区支持 4. 扩展能力 5. 使用率和稳定性 结语&#xff1a; 引言&#xff1a; 微信小程序作为一种轻量级、高效便捷的应用形式&#xff0c;已经在移动应用领域占据了重要地位。而其中&#xff0c;选择一个…

Nussbaumer Transform 以及 Amortized FHEW bootstrapping

参考文献&#xff1a; [Nuss80] Nussbaumer H. Fast polynomial transform methods for multidimensional DFTs[C]//ICASSP’80. IEEE International Conference on Acoustics, Speech, and Signal Processing. IEEE, 1980, 5: 235-237.[SV11] Smart N P, Vercauteren F. Full…

C++ 配合图形库实现画线效果

#include<stdio.h> #include <conio.h> #include<math.h> #include <graphics.h> // 引用图形库头文件 #define N 12 int List[N][N];void draw() {for (int i 0; i < N; i) {int x 200 * cos(2 * 3.14 * i / N);int y 200 * sin(2 * 3.1…

归并排序 merge Sort + 图解 + 递归 / 非递归

归并排序(merge sort)的主要思想是&#xff1a;将若干个有序序列逐步归并&#xff0c;最终归并为一个有序序列二路归并排序(2-way merge sort)是归并排序中最简单的排序方法 &#xff08;1&#xff09;二路归并排序的递归实现 // 二路归并排序的递归实现 void merge(vector&l…

Ocelot:.NET开源API网关提供路由管理、服务发现、鉴权限流等功能

随着微服务的兴起&#xff0c;API网关越来越常见。API网关是连接应用程序和用户之间的桥梁&#xff0c;就像一个交通指挥员&#xff0c;负责处理所有进出应用的数据和请求&#xff0c;确保安全、高效、有序地流通。 今天给大家推荐一个.NET开源API网关。 01 项目简介 Ocelot…

家居美学:将水离子壁炉融入你的现代装饰

当谈及家居装饰和壁炉选择时&#xff0c;水离子雾化壁炉是一个备受瞩目的话题。水离子雾化壁炉的美学价值&#xff0c;还为室内装饰带来全新的维度。它甚至能够激发室内装饰的灵感。 水离子雾化壁炉是现代美学的标志&#xff0c;融合了简洁、线条清晰的设计。这种壁炉常常采用不…

osg点云加载与渲染

目录 效果 laslib 关键代码 完整代码 效果 las点云读取使用了laslib这个库。 laslib 关键代码 {// 这里演示读取一个 .txt 点云文件const char* lasfile path.c_str();std::ifstream ifs;ifs.open(lasfile, std::ios::in | std::ios::binary);liblas::ReaderFactory f;libl…

给CAD中添加自定义菜单CUIX

本文以AutoCAD2020为例&#xff0c;介绍如何添加自定义菜单。 打开AutoCAD2020&#xff0c;在命令行执行CUI并回车&#xff0c;出现菜单 进入菜单编辑界面 点击传输&#xff0c;然后新建 在菜单上右键&#xff0c;添加自定义菜单 点击保存&#xff0c;即可存为cuix文件。之后…

if,switch语句

1.if public class IfDemo1 {public static void main(String[] args) {// 目标&#xff1a;掌握if分支三种形式的用法和执行流程// 需求&#xff1a;测量用户体温&#xff0c;发现高于37度就报警double temperature 38.5;if (temperature > 37){System.out.println("…

基于PHP的设云尘资讯网站设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

JUC包下面的四大天王+线程池部分知识

一)Semphore:限流器用我就对了 Java中信号量Semphore是把操作系统原生的信号量封装了一下&#xff0c;本质就是一个计数器&#xff0c;描述了 可用资源的个数&#xff0c;主要涉及到两个操作 如果计数器为0了&#xff0c;继续Р操作&#xff0c;就会出现阻塞等待的情况 P操作:申…

Ribbon 负载均衡原理和策略

目录 一、Ribbon 是什么 二、Ribbon 负载均衡原理 三、Ribbon 负载均衡策略 四、Ribbon的应用场景 一、Ribbon 是什么 Ribbon是一个开源的、基于HTTP和TCP的客户端负载均衡工具&#xff0c;它提供了一个简单的、基于配置的负载均衡策略&#xff0c;可以帮助开发人员更轻松…

苹果M3处理器跑分曝光,单核无敌!

10月底&#xff0c;苹果发布了全新的M3、M3 Pro、M3 Max芯片以及搭载M3系列芯片的3款新硬件&#xff0c;包括&#xff1a;新款24英寸iMac、新款14/16英寸MacBook Pro。 根据苹果官方介绍&#xff0c;M3系列芯片基于台积电3纳米工艺打造&#xff0c;采用全新图形处理器架构&…

【电工基础】

电工基础 11.1 简介1.2 电路作用1.3 电路模型1.4 电流定义1.5 电压定义1.6 电动势1.7 电阻元件1.7.1 电阻元件定义1.7.2 电阻原件的特性1.7.31.7.4 1.81.91.10 345 1 1.1 简介 电源外部&#xff0c;正电荷移动的方向是由电源正极向电源负极方向&#xff0c;负电荷移动的方向是…

C语言--输入10个数字,要求输出其中值最大的元素和该数字是第几个数

今天小编带大家了解一下什么是“打擂台”算法。 一.思路分析 可以定义一个数组arr&#xff0c;长度为10&#xff0c;用来存放10个数字&#xff0c;设计一个函数Max&#xff0c;用来求两个数中的较大值&#xff0c; 定义一个临时变量tmparr[0],保存临时最大的值&#xff0c;下标…