如何用 Chaquopy 和 openCV 打开 android 相机?
How to open android Camera with Chaquopy and openCV?
我为图像识别任务执行 python 代码,它工作得很好,但是当我使用 Chaquopy 将它实现到 android 应用程序时,它不起作用。这是因为 python 代码中的第一条指令旨在使用此指令 cap = cv2.videoCapture(0) 打开相机,并且此指令在 android 设备上不起作用。
我还在 androidManifest.xml 中添加了相机和存储权限
这是我的 Java 代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (! Python.isStarted()) {
Python.start(new AndroidPlatform(this));
}
Python py = Python.getInstance();
PyObject pym =py.getModule("MyPythonClass");
}
这是 python 代码(class 的名称是 MyPythonClass.py):
import numpy as np
from skimage.transform import pyramid_gaussian
from imutils.object_detection import non_max_suppression
import imutils
from skimage.feature import hog
from sklearn.externals import joblib
from skimage import color
import matplotlib.pyplot as plt
import os
import glob
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import argparse
import time
import cv2
min_wdw_sz = [68, 124]
step_size = [10, 10]
orientations = 9
pixels_per_cell = [6, 6]
cells_per_block = [2, 2]
visualize = False
normalize = True
threshold = .3
clf = joblib.load(os.path.join('/storage/emulated/0/Download/', 'svm.model'))
def sliding_window(image, window_size, step_size):
for y in range(0, image.shape[0], step_size[1]):
for x in range(0, image.shape[1], step_size[0]):
yield (x, y, image[y: y + window_size[1], x: x + window_size[0]])
webcam = cv2.VideoCapture (0)
# loop over the frames from the video stream
while True:
ret, frame = webcam.read()
im = imutils.resize(frame, width=min(300, frame.shape[1]))
orig = im.copy()
min_wdw_sz = (64, 128)
step_size = (10, 10)
downscale = 1.25
#List to store the detections
detections = []
#The current scale of the image
scale = 0
for im_scaled in pyramid_gaussian(im, downscale = downscale):
#The list contains detections at the current scale
if im_scaled.shape[0] < min_wdw_sz[1] or im_scaled.shape[1] < min_wdw_sz[0]:
break
for (x, y, im_window) in sliding_window(im_scaled, min_wdw_sz, step_size):
if im_window.shape[0] != min_wdw_sz[1] or im_window.shape[1] != min_wdw_sz[0]:
continue
im_window = color.rgb2gray(im_window)
fd = hog(im_window, orientations, pixels_per_cell, cells_per_block, transform_sqrt=normalize)
fd = fd.reshape(1, -1)
pred = clf.predict(fd)
if pred == 1:
if clf.decision_function(fd) > 1:
detections.append((int(x * (downscale**scale)), int(y * (downscale**scale)), clf.decision_function(fd),
int(min_wdw_sz[0] * (downscale**scale)),
int(min_wdw_sz[1] * (downscale**scale))))
scale += 1
clone = im.copy()
# loop over the detections
for (x_tl, y_tl, _, w, h) in detections:
cv2.rectangle(im, (x_tl, y_tl), (x_tl + w, y_tl + h), (0, 255, 0), thickness = 2)
rects = np.array([[x, y, x + w, y + h] for (x, y, _, w, h) in detections])
sc = [score[0] for (x, y, score, w, h) in detections]
sc = np.array(sc)
pick = non_max_suppression(rects, probs = sc, overlapThresh = 0.3)
# print "shape, ", pick.shape
for(xA, yA, xB, yB) in pick:
cv2.rectangle(clone, (xA, yA), (xB, yB), (0, 45, 255), 2)
# show the output frame
cv2.imshow("Frame", clone)
这就是 logact 显示的错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com........MainActivity}: com.chaquo.python.PyException: AttributeError: 'NoneType' object has no attribute 'shape'
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access00(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: com.chaquo.python.PyException: AttributeError: 'NoneType' object has no attribute 'shape'
at <python>.<module>(/android_asset/chaquopy/app.zip/MyPythonClass.py:44)
编辑:
在 phone 中授予权限(存储和摄像头)。
和:minSdkVersion 19
targetSdk版本 28
compileSdkVersion 28
我认为 OpenCV 对本机 Android 相机 API 有一些支持,但它显然不适用于当前的 Chaquopy 构建。正如您在 中发现的那样,最简单的解决方法是在 Java 中捕获图像,然后将其作为字节数组传输到 Python。
我为图像识别任务执行 python 代码,它工作得很好,但是当我使用 Chaquopy 将它实现到 android 应用程序时,它不起作用。这是因为 python 代码中的第一条指令旨在使用此指令 cap = cv2.videoCapture(0) 打开相机,并且此指令在 android 设备上不起作用。 我还在 androidManifest.xml 中添加了相机和存储权限 这是我的 Java 代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (! Python.isStarted()) {
Python.start(new AndroidPlatform(this));
}
Python py = Python.getInstance();
PyObject pym =py.getModule("MyPythonClass");
}
这是 python 代码(class 的名称是 MyPythonClass.py):
import numpy as np
from skimage.transform import pyramid_gaussian
from imutils.object_detection import non_max_suppression
import imutils
from skimage.feature import hog
from sklearn.externals import joblib
from skimage import color
import matplotlib.pyplot as plt
import os
import glob
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import argparse
import time
import cv2
min_wdw_sz = [68, 124]
step_size = [10, 10]
orientations = 9
pixels_per_cell = [6, 6]
cells_per_block = [2, 2]
visualize = False
normalize = True
threshold = .3
clf = joblib.load(os.path.join('/storage/emulated/0/Download/', 'svm.model'))
def sliding_window(image, window_size, step_size):
for y in range(0, image.shape[0], step_size[1]):
for x in range(0, image.shape[1], step_size[0]):
yield (x, y, image[y: y + window_size[1], x: x + window_size[0]])
webcam = cv2.VideoCapture (0)
# loop over the frames from the video stream
while True:
ret, frame = webcam.read()
im = imutils.resize(frame, width=min(300, frame.shape[1]))
orig = im.copy()
min_wdw_sz = (64, 128)
step_size = (10, 10)
downscale = 1.25
#List to store the detections
detections = []
#The current scale of the image
scale = 0
for im_scaled in pyramid_gaussian(im, downscale = downscale):
#The list contains detections at the current scale
if im_scaled.shape[0] < min_wdw_sz[1] or im_scaled.shape[1] < min_wdw_sz[0]:
break
for (x, y, im_window) in sliding_window(im_scaled, min_wdw_sz, step_size):
if im_window.shape[0] != min_wdw_sz[1] or im_window.shape[1] != min_wdw_sz[0]:
continue
im_window = color.rgb2gray(im_window)
fd = hog(im_window, orientations, pixels_per_cell, cells_per_block, transform_sqrt=normalize)
fd = fd.reshape(1, -1)
pred = clf.predict(fd)
if pred == 1:
if clf.decision_function(fd) > 1:
detections.append((int(x * (downscale**scale)), int(y * (downscale**scale)), clf.decision_function(fd),
int(min_wdw_sz[0] * (downscale**scale)),
int(min_wdw_sz[1] * (downscale**scale))))
scale += 1
clone = im.copy()
# loop over the detections
for (x_tl, y_tl, _, w, h) in detections:
cv2.rectangle(im, (x_tl, y_tl), (x_tl + w, y_tl + h), (0, 255, 0), thickness = 2)
rects = np.array([[x, y, x + w, y + h] for (x, y, _, w, h) in detections])
sc = [score[0] for (x, y, score, w, h) in detections]
sc = np.array(sc)
pick = non_max_suppression(rects, probs = sc, overlapThresh = 0.3)
# print "shape, ", pick.shape
for(xA, yA, xB, yB) in pick:
cv2.rectangle(clone, (xA, yA), (xB, yB), (0, 45, 255), 2)
# show the output frame
cv2.imshow("Frame", clone)
这就是 logact 显示的错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com........MainActivity}: com.chaquo.python.PyException: AttributeError: 'NoneType' object has no attribute 'shape'
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access00(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: com.chaquo.python.PyException: AttributeError: 'NoneType' object has no attribute 'shape'
at <python>.<module>(/android_asset/chaquopy/app.zip/MyPythonClass.py:44)
编辑:
在 phone 中授予权限(存储和摄像头)。 和:minSdkVersion 19 targetSdk版本 28 compileSdkVersion 28
我认为 OpenCV 对本机 Android 相机 API 有一些支持,但它显然不适用于当前的 Chaquopy 构建。正如您在