Глубина изображения OpenCV повреждена JSON

Я работаю над проектом, который требует перенос кадров OpenCV с использованием JSON, где кадры используются в CascadeClassifier на принимающей стороне. Я столкнулся с ошибкой в ​​CascadeClassifier:

Kyles-MBP:facial_detection kyle$ python3 badcv.py
Traceback (most recent call last):
  File "badcv.py", line 30, in <module>
    doesnt()
  File "badcv.py", line 26, in doesnt
    faces = cascade.detectMultiScale(imgnew)
cv2.error: OpenCV(3.4.2) /Users/travis/build/skvark/opencv-python/opencv/modules/objdetect/src/cascadedetect.cpp:1376: error: (-215:Assertion failed) scaleFactor > 1 && _image.depth() == 0 in function 'detectMultiScale'

Kyles-MBP:facial_detection kyle$

Я выделил свой код, чтобы изолировать ошибку ниже. Очевидно, что я делаю что-то не так, но у меня недостаточно опыта работы с OpenCV, чтобы знать, что здесь делать. Я сделал некоторые поиски, и глубина изображения 0 соответствует CV_8UОднако я понятия не имею, как установить такую ​​глубину (я провел поиск и пришел к выводу, что это не должно иметь значения, так как cv2 изначально представляет изображения как ndarray, но это может быть ложным предположением). Кроме того, я не могу определить разницу между до и после ndarray; по моей оценке, по всем показателям, кроме физического расположения в памяти, массивы pre и post идентичны. Я включил выходные данные интерпретатора из исследования структур данных.

Что я делаю не так, и как мне избежать этой конкретной ошибки? Спасибо!

Код:

# badcv.py
import cv2
import json
import numpy as np
import os
import sys

cascade_file_path = os.path.dirname(
    os.path.realpath(__file__)) + '/default.xml'

def works():
    img = cv2.imread(sys.argv[1])
    imgnew = img

    rows, cols = imgnew.shape[:2]
    cascade = cv2.CascadeClassifier(cascade_file_path)

    faces = cascade.detectMultiScale(imgnew)

def doesnt():
    img = cv2.imread(sys.argv[1])
    data = { 'file': json.dumps(img.tolist()) }
    imgnew = np.array(json.loads(data['file']))

    if not (img is imgnew):
        print("Not the same object")

    rows, cols = imgnew.shape[:2]
    cascade = cv2.CascadeClassifier(cascade_file_path)

    faces = cascade.detectMultiScale(imgnew)

if __name__ == "__main__":
    works()
    doesnt()

В качестве дополнения: default.xml file является классификатором Haar xml, который поставляется вместе с OpenCV, и я использую простой тестовый файл с разрешением 10px X 20px, однако этот скрипт все еще не работает на изображениях любого размера, включая jpg и png.

Равенство:

Я также проверил на равенство объектов, и следующее утверждение верно:

>>> if (img == imgnew).all(): print("element-wise equality)
'element-wise equality'

Однако равенство на уровне объекта недопустимо (что имеет смысл, потому что json.loads вернет новый словарь, а не кэшированный в памяти):

>>> if not (img is imgnew): print("not the same object")
'not the same object'

Типы обоих img а также imgnew являются ndarray с той же формы:

>>> if type(img) is type(imgnew): print("same type")
'same type'
>>> type(img)
<class 'numpy.ndarray'>
>>> if img.shape == imgnew.shape: print("same shape")
'same shape'

1 ответ

Решение

Я провел некоторый поиск, и глубина изображения 0 соответствует CV_8U, однако я не знаю, как установить такую ​​глубину

Вы были на правильном пути. Это битовая глубина изображения, тип данных каждого пикселя. img будет загружен с dtype np.uint88-разрядное целое число без знака, такое же, как CV_8U.

Когда вы проходите через json, значения пикселей становятся целыми числами Python, а созданный массив numpy будет иметь np.int64 DTYPE.

Таким образом, проблема:

>>> img.dtype == imgnew.dtype
False

Можно исправить с помощью:

# Create an array with 8-Bit unsigned integers
imgnew_u8 = imgnew.astype(np.uint8)
Другие вопросы по тегам