OpenCV On Android开发 - Android Studio上环境配置

简介: OpenCV On Android开发 - Android Studio上环境配置

在Android Studio 2.2上集成OpenCV4Android SDK

OpenCV官方的教程是基于Eclipse配置开发环境,但是Eclipse已经被Google抛弃了,所以我是写这篇文章的前三天刚刚开始用Android Studio 2.2版本,很多Gradle脚本也不熟悉,只能各种查找。经过一番痛苦的领悟终于把OpenCV4Android集成到我在Android Studio中创建的项目上了,并且写了测试程序。下面说一下如何实现集成步骤,首先是准备工作要做好:

  • 下载好Android Studio 2.2版本
  • 下载好OpenCV4AndroidSDK - 去OpenCV社区官网即可得到。
  • 下载之后解压缩到D:\OpenCV-2.4.11-android-sdk\OpenCV-android-sdk

  • apk目录里面放的是OpenCV Manager的安装文件,是不同CPU版本要选择不同apk安装文件,这种方式调用OpenCV比较麻烦。不推荐!
  • doc目录里面放的是相关文档与OpenCV的LOGO
  • samples里面放的是OpenCV4Android的演示代码,参考价值很大,值得关注
  • sdk里面放内容就是我们要重点关注的,集成到Android Studio中的项目上去的东西。
    双击打开sdk文件夹就会看到:

准备工作做好之后,首先就是要在Android Studio中创建一个Android项目,创建好之后,选择File->New->Import Module

然后选择到SDK路径下的JAVA


导入之后,你就会看到

就说明成功导入了,然后打开Module Settings

添加依赖之后,就可以在项目中引用OpenCV相关API代码了,如果你此刻运行测试apk程序,它就会提示你安装OpenCV Manager这个东西。对多数开发者来说这不算配置成功,这样自己的APP就无法独立安装,必须依赖OpenCV Manager这个apk文件才可以运行,这个时候就该放大招来解决这个问题,

首先把我们准备阶段看到SDK下面native文件下所有的文件都copy到你创建好的项目libs目录下,然后在gradle中加上如下一段脚本:

task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}

然后还要加上这句话:

compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')

最后一步,检查一下gradle文件:

如此配置之后你就再也不需要其它任何配置了,这样既避免了NDK繁琐又不用依赖OpenCV Manager第三方APP,你的APP就可以直接使用OpenCV了。

特别说明:

此配置方式OpenCV加载必须通过静态加载方式,以下为Demo测试程序代码:

package com.example.administrator.helloworld;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.view.ActionMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.io.InputStream;

import static android.widget.Toast.makeText;

public class MainActivity extends AppCompatActivity {
    private double max_size = 1024;
    private int PICK_IMAGE_REQUEST = 1;
    private ImageView myImageView;
    private Bitmap selectbp;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        staticLoadCVLibraries();
        myImageView = (ImageView)findViewById(R.id.imageView);
        myImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        Button selectImageBtn = (Button)findViewById(R.id.select_btn);
        selectImageBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // makeText(MainActivity.this.getApplicationContext(), "start to browser image", Toast.LENGTH_SHORT).show();
                selectImage();
            }
        });

        Button processBtn = (Button)findViewById(R.id.process_btn);
        processBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // makeText(MainActivity.this.getApplicationContext(), "hello, image process", Toast.LENGTH_SHORT).show();
                convertGray();
            }
        });

    }

    //OpenCV库静态加载并初始化
    private void staticLoadCVLibraries(){
        boolean load = OpenCVLoader.initDebug();
        if(load) {
            Log.i("CV", "Open CV Libraries loaded...");
        }
    }

    private void convertGray() {
        Mat src = new Mat();
        Mat temp = new Mat();
        Mat dst = new Mat();
        Utils.bitmapToMat(selectbp, src);
        Imgproc.cvtColor(src, temp, Imgproc.COLOR_BGRA2BGR);
        Log.i("CV", "image type:" + (temp.type() == CvType.CV_8UC3));
        Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);
        Utils.matToBitmap(dst, selectbp);
        myImageView.setImageBitmap(selectbp);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri uri = data.getData();
            try {
                Log.d("image-tag", "start to decode selected image now...");
                InputStream input = getContentResolver().openInputStream(uri);
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(input, null, options);
                int raw_width = options.outWidth;
                int raw_height = options.outHeight;
                int max = Math.max(raw_width, raw_height);
                int newWidth = raw_width;
                int newHeight = raw_height;
                int inSampleSize = 1;
                if(max > max_size) {
                    newWidth = raw_width / 2;
                    newHeight = raw_height / 2;
                    while((newWidth/inSampleSize) > max_size || (newHeight/inSampleSize) > max_size) {
                        inSampleSize *=2;
                    }
                }

                options.inSampleSize = inSampleSize;
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                selectbp = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);

                myImageView.setImageBitmap(selectbp);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void selectImage() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"选择图像..."), PICK_IMAGE_REQUEST);
    }
}

选择一张图像加载之后显示:

点击【处理】之后,通过调用OpenCV API实现了灰度转换

特别说明:这种方式调用OpenCV无需NKD以及安装OpenCV Manager。应该是广大Android开发人员最喜欢的一种方式。

免费环境搭建视频查看

OpenCV For Android 基础入门视频

相关文章
|
5天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
21 5
|
4天前
|
设计模式 IDE Java
探索安卓开发:从新手到专家的旅程
【10月更文挑战第22天】 在数字时代的浪潮中,移动应用开发如同一座金矿,吸引着无数探险者。本文将作为你的指南针,指引你进入安卓开发的广阔天地。我们将一起揭开安卓平台的神秘面纱,从搭建开发环境到掌握核心概念,再到深入理解安卓架构。无论你是初涉编程的新手,还是渴望进阶的开发者,这段旅程都将为你带来宝贵的知识和经验的财富。让我们开始吧!
|
12天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
52 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
4天前
|
搜索推荐 Android开发 UED
安卓开发中的自定义视图:打造个性化用户界面
【10月更文挑战第22天】在安卓应用的海洋中,如何让你的应用脱颖而出?一个独特且直观的用户界面(UI)至关重要。本文将引导你通过自定义视图来打造个性化的用户体验,从基础的视图绘制到触摸事件的处理,我们将一步步深入探讨。准备好了吗?让我们开始吧!
|
4天前
|
Android开发
我是一位Android工程师,用通义灵码的AS插件做开发工作助手,对比之前没有灵码,现在提效了60%
我是一位Android工程师,用通义灵码的AS插件做开发工作助手,对比之前没有灵码,现在提效了60%
15 0
|
17天前
|
消息中间件 存储 前端开发
资深Android开发的5个经典面试题
本文首发于公众号“AntDream”,欢迎关注。文章详细解答了五个常见的Android面试题,涵盖内存泄漏与溢出、Binder机制、MVC/MVP/MVVM架构、Handler机制及Context对象等内容,帮助读者深入了解Android开发的核心概念。
21 0
|
18天前
|
存储 安全 Android开发
探索Android开发之旅:从新手到专家的蜕变之路
【10月更文挑战第8天】在这篇文章中,我们将共同踏上一段激动人心的旅程,深入探索Android开发的奥秘。无论你是初涉编程世界的新手,还是渴望提升技能的开发者,这里都有你需要的知识与启示。通过简洁明了的语言和实际案例,我们将一起解锁Android开发的核心概念、掌握关键技能,并最终实现从新手到专家的华丽转变。
|
19天前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
173 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
2月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
44 4
|
2月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制