JSON破坏了OpenCV图像深度

时间:2018-08-10 00:31:17

标签: python python-3.x opencv cascade-classifier

我正在一个项目中,该项目要求使用JSON传输OpenCV帧,其中这些帧在接收端的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之间的任何区别;据我估计,除内存中的物理位置外,在所有度量上,前置和后置数组是相同的。我在下面的调查数据结构中包括了解释器的输出。

我在做什么错,如何避免遇到此特定错误?谢谢!

代码:

# 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文件是OpenCV附带的Haar xml分类器,我使用的是10px X 20px的简单测试文件,但是此脚本在所有大小的jpg图像上仍然无法通过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'

imgimgnew的类型均为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 :(得分:1)

  

我做了一些搜索,图像深度0对应于CV_8U,但是我不知道如何设置这样的深度

您在正确的轨道上。这是图像的位深度,即每个像素的数据类型。 img将被加载np.uint8的dtype,它是一个无符号的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)