在android app工程中调用python代码

部署运行你感兴趣的模型镜像

本示例以Chaquopy 16.0为基础实现,使用android studio 版本android-studio-2024.2.2.13-linux。

1、直接用android studio新建一个Native C++工程(其他类型工程我没有试过,不清除是否可行)

2、修改gradle相关文件:

2.1 修改./gradle/libs.versions.toml

        

[versions]
agp = "8.8.0"
pgp = "16.0.0"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
appcompat = "1.7.0"
material = "1.12.0"
constraintlayout = "2.2.1"

[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-python = { id = "com.chaquo.python", version.ref = "pgp" }

第3行pgp = "16.0.0"和最后一行android-python = { id = "com.chaquo.python", version.ref = "pgp" }是添加的必要设置。

2.2 修改./build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.android.python) apply false
}

其中alias(libs.plugins.android.python) apply false是添加的必要配置。

2.3 修改./app/build.gradle

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.android.python)
}

android {
    namespace 'com.example.myapplication'
    compileSdk 35

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 30
        targetSdk 35
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        python {
            pip {
                install "six"
                install "opencv-python"
            }
        }
        ndk {
            abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.22.1'
        }
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {

    implementation libs.appcompat
    implementation libs.material
    implementation libs.constraintlayout
    testImplementation libs.junit
    androidTestImplementation libs.ext.junit
    androidTestImplementation libs.espresso.core
}

其中

        python {
            pip {
                install "six"
                install "opencv-python"
            }
        }
        ndk {
            abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
        }

为添加必要设置,pip部分可以按照自身需要的python库进行设置。

3.添加python代码

在./app/src/main目录下创建python目录

在./app/src/main/python目录下创建python源码文件,如main.py

from six.moves import input
import cv2 as cv
import numpy as np
from gaussian_mix import make_gaussians

def main(dir=""):
    print("Enter your name, or an empty line to exit.")
    cluster_n = 5
    img_size = 512

    # generating bright palette
    colors = np.zeros((1, cluster_n, 3), np.uint8)
    colors[0,:] = 255
    colors[0,:,0] = np.arange(0, 180, 180.0/cluster_n)
    colors = cv.cvtColor(colors, cv.COLOR_HSV2BGR)[0]
    print(colors.shape)
    print('sampling distributions...')
    points, _ = make_gaussians(cluster_n, img_size)

    term_crit = (cv.TERM_CRITERIA_EPS, 30, 0.1)
    _ret, labels, _centers = cv.kmeans(points, cluster_n, None, term_crit, 10, 0)

    img = np.zeros((img_size, img_size, 3), np.uint8)
    for (x, y), label in zip(np.int32(points), labels.ravel()):
       c = list(map(int, colors[label]))

       cv.circle(img, (x, y), 1, c, -1)
    print(img.shape)
    cv.imwrite(dir + "/" + "img.png", img)
    return "python test out"
gaussian_mix.py
#!/usr/bin/env python

# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3

if PY3:
    xrange = range

import numpy as np
import cv2 as cv

from numpy import random

def make_gaussians(cluster_n, img_size):
    points = []
    ref_distrs = []
    for _i in xrange(cluster_n):
        mean = (0.1 + 0.8*random.rand(2)) * img_size
        a = (random.rand(2, 2)-0.5)*img_size*0.1
        cov = np.dot(a.T, a) + img_size*0.05*np.eye(2)
        n = 100 + random.randint(900)
        pts = random.multivariate_normal(mean, cov, n)
        points.append( pts )
        ref_distrs.append( (mean, cov) )
    points = np.float32( np.vstack(points) )
    return points, ref_distrs

def draw_gaussain(img, mean, cov, color):
    x, y = mean
    w, u, _vt = cv.SVDecomp(cov)
    ang = np.arctan2(u[1, 0], u[0, 0])*(180/np.pi)
    s1, s2 = np.sqrt(w)*3.0
    cv.ellipse(img, (int(x), int(y)), (int(s1), int(s2)), ang, 0, 360, color, 1, cv.LINE_AA)


def main():
    cluster_n = 5
    img_size = 512

    print('press any key to update distributions, ESC - exit\n')

    while True:
        print('sampling distributions...')
        points, ref_distrs = make_gaussians(cluster_n, img_size)

        print('EM (opencv) ...')
        em = cv.ml.EM_create()
        em.setClustersNumber(cluster_n)
        em.setCovarianceMatrixType(cv.ml.EM_COV_MAT_GENERIC)
        em.trainEM(points)
        means = em.getMeans()
        covs = em.getCovs()  # Known bug: https://github.com/opencv/opencv/pull/4232
        found_distrs = zip(means, covs)
        print('ready!\n')

        img = np.zeros((img_size, img_size, 3), np.uint8)
        for x, y in np.int32(points):
            cv.circle(img, (x, y), 1, (255, 255, 255), -1)
        for m, cov in ref_distrs:
            draw_gaussain(img, m, cov, (0, 255, 0))
        for m, cov in found_distrs:
            draw_gaussain(img, m, cov, (0, 0, 255))

        cv.imshow('gaussian mixture', img)
        ch = cv.waitKey(0)
        if ch == 27:
            break

    print('Done')


if __name__ == '__main__':
    print(__doc__)
    main()
    cv.destroyAllWindows()

4. 添加调用python的代码


        if (!Python.isStarted())
        {
            Python.start(new AndroidPlatform(this));
        }
        Python py = Python.getInstance();
        Log.d(this.getPackageName().toString(), "python test start");
        PyObject pyObject = py.getModule("main").callAttr("main", this.getFilesDir().getPath());
        Log.d(this.getPackageName().toString(), pyObject.toString());

其中


        if (!Python.isStarted())
        {
            Python.start(new AndroidPlatform(this));
        }
        Python py = Python.getInstance();

是初始化,获得python执行对象代码

其中

PyObject pyObject = py.getModule("main").callAttr("main", this.getFilesDir().getPath());

是调用main.py中的main函数,传递一个路径为参数,接收函数的返回值。

同时也可以参考Android App开发教程(二)——透过Chaquopy结合Python第三方库numpy安装与应用-优快云博客

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值