首頁>科技>

最近閒來無事,研究研究在安卓上跑 Python,想起以前玩過的 kivy 技術,kivy 是一個跨平臺的 UI 框架,當然對我們最有用的是,kivy 可以把 Python 程式碼打包成安卓應用。

但是由於安卓打包的工具鏈很長,包括 Android Sdk 打包 Java 程式碼、NDK 編譯 Python、 編譯各種 Python 依賴包,經常花一整天從入門到放棄。

這次使出認真研究的心態,終於找到一個解決方案,於是有了這篇文章。

只要會 Python 就能寫安卓 App,無需安卓開發基礎,無需編譯手機上也有互動式 Python 直譯器,直接除錯 Python 程式碼可以使用各種 Python 庫,包括 numpy/opencv 等機器學習包可以與安卓介面互動,使用手機硬體,比如攝像頭

那麼我們就以人臉識別 App 為例,看看如何簡單幾步搞定,先看看成品的效果。

1、安裝 airport.apk

AirPort 是我編譯好的一個安卓 App,裡面包含了 Python 直譯器和一些常用的依賴庫。

2、連線手機的 Python 直譯器

啟動手機上的 AirPort 應用,就會執行 Python 直譯器,為了除錯的方便,應用內建了一個 ssh 伺服器,啟動的時候會顯示手機的 IP 地址。

在電腦上使用 ssh 命令,就可以連線到手機。

ps: 注意:確保你的手機和電腦在同一區域網中。

# 在電腦上連線手機,注意這裡ip需要替換成AirPort顯示的ipssh -p 8000 [email protected]# 輸入密碼,這裡密碼是固定為:meteorixmeteorix

然後你就可以在手機上盡情使用 Python 了。

3、攝像頭的 App

在 kivy 的官方文件中,我們可以找到這樣一個攝像頭的 example

程式碼非常簡單,Builder.load_string 函式載入了一段配置,這是 kivy 提供的 UI 定義語言 kivy language。

from kivy.app import Appfrom kivy.lang import Builderfrom kivy.uix.boxlayout import BoxLayoutimport timeBuilder.load_string('''<CameraClick>: orientation: 'vertical' Camera: id: camera resolution: (640, 480) play: False ToggleButton: text: 'Play' on_press: camera.play = not camera.play size_hint_y: None height: '48dp' Button: text: 'Capture' size_hint_y: None height: '48dp' on_press: root.capture()''')class CameraClick(BoxLayout):def capture(self):''' Function to capture the images and give them the names according to their captured time and date. ''' camera = self.ids['camera'] timestr = time.strftime("%Y%m%d_%H%M%S") camera.export_to_png("IMG_{}.png".format(timestr)) print("Captured")class TestCamera(App):def build(self):return CameraClick()TestCamera().run()

將這段程式碼儲存為 kvmain.py 檔案,我們可以直接在電腦上執行,如果你的電腦有攝像頭,就可以看到攝像頭 App 的效果。

4、推送程式碼到安卓手機

這一步需要做的就是,把這個攝像頭 App 推送到安卓手機上,然後啟動 AirPort 應用,將 kvmain.py 推送到手機 /sdcard/kv/kvmain.py 路徑,然後啟動 AirPort 應用,就會載入這個路徑下的 Python 程式碼。

adb shell mkdir -p /sdcard/kvadb push kvmain.py /sdcard/kv/kvmain.py

重新啟動手機上的 AirPort 應用,即可看到我們的攝像頭 App 執行在手機上了。

5、增加人臉識別功能

這一步,我們主要用到了 opencv 的人臉識別介面。

import cv2detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')img = cv2.imread('faces.jpg')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)faces = detector.detectMultiScale(gray, 1.3, 5)print(faces)

最後修改 App 程式碼,讀取攝像頭的圖片,呼叫 opencv 人臉識別介面,將識別出來的人臉座標,畫到手機螢幕的對應位置上。

bbox = BoundingBox(name=face_name, size_hint=(None, None))...for loc in faces:# calculate position of the face x, y, w, h = loc t = int(anchor_t - y*sh) b = int(anchor_t - (y+h)*sh) r = int(anchor_l + x*sw) l = int(anchor_l + (x+w)*sw)# update bounding box bbox.pos = (int(l), int(b)) bbox.size = (int(r-l), int(t-b)) ...

當然,我們還需要針對安卓手機進行一些除錯,我們再次推送程式碼到手機上。

adb push src/* /sdcard/kv/

重啟應用就可以看到上文展示的 GIF 效果了。

  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 中國虛擬現實應用狀況白皮書(2018年)