yama_coco
@yama_coco (山﨑 壮太)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

KotlinのChaquopyを使ってPythonのOpenCVを使いたい

解決したいこと

KotlinのChaquopyを使ってpythonファイルのOpenCVを流すときに下記のようなエラーが出ます。
ある画像と用意した画像群を一つずつ比較して類似度を算出するPythonファイルをKotlinから実行して戻り値をMainAcvivity.ktに戻したいです。

発生している問題・エラー

com.chaquo.python.PyException: error: OpenCV(4.5.1) /home/smith/git/chaquo/python/server/pypi/packages/opencv-python/build/4.5.1.48/cp38-cp38-android_21_arm64_v8a/src/opencv/modules/imgproc/src/resize.cpp:4051: error: (-215:Assertion failed) !ssize.empty() in function 'resize'

該当するソースコード

MainActivity.kt
            // Pythonコードを実行する前にPython.start()の呼び出し
            if (!Python.isStarted()) {
                Python.start(AndroidPlatform(this))
            }

            val py = Python.getInstance()
            val module = py.getModule("templatePython/template") // スクリプト名

            try {
                val number = module.callAttr("template_image").toFloat()
                binding.textView2.text = number.toString()
            } catch (e: PyException) {
                Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
            }

templatePython/template.pyのtemplate_imageという関数から一番低い類似度を取得して画面に出すという動きを期待しているのですが、例外を吐いてしまいます。

ちなみに動かしたいPythonファイルの中身は

template.py
import cv2
import os

def template_image():
    TARGET_FILE = 'importImage.jpg'
    IMG_DIR = os.path.abspath(os.path.dirname(__file__)) + '/compiringImages/'
    IMG_SIZE = (200, 200)

    target_img = cv2.imread(TARGET_FILE, cv2.IMREAD_GRAYSCALE)
    target_img = cv2.resize(target_img, IMG_SIZE)

    bf = cv2.BFMatcher(cv2.NORM_HAMMING)
    # detector = cv2.ORB_create()
    detector = cv2.AKAZE_create()
    (target_kp, target_des) = detector.detectAndCompute(target_img, None)

    print('TARGET_FILE: %s' % (TARGET_FILE))

    files = os.listdir(IMG_DIR)
    rets = []
    for file in files:
        if file == '.DS_Store' or file == TARGET_FILE:
            continue

        comparing_img_path = IMG_DIR + file
        try:
            comparing_img = cv2.imread(comparing_img_path, cv2.IMREAD_GRAYSCALE)
            comparing_img = cv2.resize(comparing_img, IMG_SIZE)
            (comparing_kp, comparing_des) = detector.detectAndCompute(comparing_img, None)
            matches = bf.match(target_des, comparing_des)
            dist = [m.distance for m in matches]
            ret = sum(dist) / len(dist)
        except cv2.error:
            ret = 100000

        rets.append(ret)
        print(file, ret)

    print(min(rets))

    return min(rets)

ディレクトリは以下のような配置になっています。

└── Main/
    ├── Java/
    │   └── com.example.project/
    │       └── MainActivity.kt
    └── Python/
        └── templatePython/
            ├── compiringImages/
            │   ├── 1.jpg
            │   ├── 2.jpg
            │   ├── 3.jpg
            │   ├── 4.jpg
            │   └── 5.jpg
            ├── importImage.jpg
            └── template.py

参考にした記事

自分で試したこと

リサイズするときに読み込んだファイルが空なので怒られていると解釈しているのですが、画像のパスが悪いのかと思い絶対パスで記述しても同じエラーになりました。
ターミナルで直接Pythonファイルを実行するとうまく動きました。
Chaquopyで動かすとエラーが出てしまいます。

どなたか解決策ご存知の方いましたらご教示いただきたいです。

0

1Answer

Javaの作業ディレクトリとPython単体で動かした時のカレントディレクトリが不一致でパスがズレてそうな感は確かにありそう。
IMG_DIRはjava実行時、Python単体実行時どっちも同じパスになります?

0Like

Comments

Your answer might help someone💌