如何使用Chaquopy和openCV打开android相机?

时间:2019-08-23 15:50:28

标签: python android opencv camera chaquopy

我执行用于图像识别任务的python代码,效果很好,但是当我使用Chaquopy将其实现到android应用程序中时,它不起作用。这是因为python代码中的第一个指令旨在使用此指令上限= 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代码(该类的名称为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.access$1100(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)

编辑:

权限(存储和摄像头)在电话中授予。 和:minSdkVersion 19           targetSdkVersion 28           compileSdkVersion 28

1 个答案:

答案 0 :(得分:0)

我认为OpenCV支持本地Android相机API,但显然不能在当前的Chaquopy版本中使用。正如您在your other question中所发现的那样,最简单的解决方法是用Java捕获图像,然后将其作为字节数组传输到Python。