Глубина изображения 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.uint8
8-разрядное целое число без знака, такое же, как 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)