主要需要实现通过Android Studio调用服务器中开的paddlehub接口,paddlehub配置的话参考此码云仓库
。也就是需要读取图片,并进行传输到服务器,服务器处理完后返回结果即可。当然这只是一种方法,可以用PaddleMobile,也可以android studio直接调用接口,不过那个转码过程有点复杂。使用了Chaquopy,其作用是在Android Studio添加Python环境,java和Python互调。
这个可参考我这篇博文
找到项目目录的build.gradle文件。
按照下图添加两个语句。
第一个语句。
maven { url "https://chaquo.com/maven" }
第二个语句
classpath "com.chaquo.python:gradle:11.0.0"
至于如何确定该选哪个版本,参考官网文档。
我使用的是虚拟环境中的python3.8.11,然后看graddle的版本的话看如图那条语句就行。
选择合适的版本,替换我这上面的3.8.11即可。
找到如下图的build.graddle。
双击打开,然后替换该文件的第一条语句为下面两条。
apply plugin: 'com.android.application'
apply plugin: 'com.chaquo.python'
指定abi和配置python环境,如下图所示位置放置:
ndk代码:
ndk {
// 指定abi,如需在模拟器调试,增加"x86",否则指定"armeabi-v7a"即可
abiFilters "armeabi-v7a", "x86"
}
python环境代码:
python {
buildPython "D:/Users/Administrator/Anaconda3/envs/test/python.exe"
pip {
//options "--index-url", "https://mirrors.aliyun.com/pypi/simple/"
options "--extra-index-url", "https://pypi.tuna.tsinghua.edu.cn/simple/"
install "opencv-python"
install "requests"
}
}
其中buildPython就是python.exe的位置,可以用anaconda里面的虚拟环境中的python,配置过程参考我这篇博文。
options指定库的镜像下载地址,可选择阿里云,清华等等。
install后接库名,可以通过pandas==xxx来指定库的版本。
所有这些完成后点小锤锤build。
如果不报错,则说明环境配置没问题了。
Gradle配置完成后,项目main文件夹下会出现一个python文件夹。
右键python文件夹,创建一个python file
然后命名这个python文件,写入自己的代码即可,我这里给个demo。
from os.path import dirname, join
import requests
import json
import cv2
import base64
def cv2_to_base64(image):
data = cv2.imencode('.jpg', image)[1]
return base64.b64encode(data.tostring()).decode('utf8')
# 发送HTTP请求
def finals():
filename = join(dirname(__file__), "dog.jpg")
print(filename)
data = {'images':[cv2_to_base64(cv2.imread(filename))]}
print(data)
#print(type(cv2_to_base64(cv2.imread("D:/hb.jpg"))))
headers = {"Content-type": "application/json"}
url = "http://101.43.179.20:8866/predict/mobilenet_v3_large_imagenet_ssld"
r = requests.post(url=url, headers=headers, data=json.dumps(data))
print(r.json()["results"])
# return r.json()["results"]
可能会爆红,不用管。
接着强调一点,Chaquopy 6.3.0和更高版本中,可以使用相对于__file__的路径访问数据文件,例如,如果数据文件与Python文件位于同一目录中,使用如下命令。
from os.path import dirname, join
filename = join(dirname(__file__), "dog.jpg")
filename就算这张图片的路径了。
随便把一张图片放到py文件同目录下,改名称即可读取了。
下面那是http请求了,具体的例子参考paddlehub的实现,官网如下:
https://gitee.com/paddlepaddle/PaddleHub?_from=gitee_search
我这个端口保持开着,测试的时候可以用我服务器这个端口试试,如果关了,可联系我开一下,服务器采用的是腾讯云(没阿里云稳定)。
完成上一步后,打开MainActivity文件,添加如下函数:
void initPython(){
if (!Python.isStarted()) {
Python.start(new AndroidPlatform(this));
}
}
void callPythonCode() {
Python py = Python.getInstance();
PyObject pyObject = py.getModule("python").callAttr("finals");
}
getModule(“xxx”)中是python文件名,不需要.py后缀,然后.callAttr(“xxx”)里是python文件里的函数名,比如说我上述py文件的名字为python.py,然后要调用的函数是不需要参数的finals,就可以写成上述代码调用,然后在android的主函数调用这两个函数即可。
我这是让点击才进行识别图像。
initPython();
callPythonCode();
如果运行不报错,且有python的输出那么恭喜完成了这个流程。
我这是图像分类的demo,测试图片和返回结果如下:
Pomeranian是博美犬; 博美; 松鼠犬; 波美拉尼亚犬; 松鼠狗。