本示例以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安装与应用-优快云博客
1708

被折叠的 条评论
为什么被折叠?



