【问题标题】:Load Numpy Array Binary Image with OpenCV detectMultiScale使用 OpenCV detectMultiScale 加载 Numpy 数组二进制图像
【发布时间】:2017-07-27 04:16:04
【问题描述】:

我有最初来自我用 OpenCV 操作的 Mnist 数据集的数字序列。它们保存在 pickle 文件中。它们是形状为 (112, 112) 的 1 通道图像。

我想通过 OpenCV 级联分类器运行这些,类似于 the face detection tutorial,但使用这些 Google-Street-View-House-Numbers-Digit-Localization cascades

这是我的尝试:

data = p.load_file('data/train_sequences00.pickle')
zero = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade0/cascade.xml')
one = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade1/cascade.xml')
two = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade2/cascade.xml')
three = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade3/cascade.xml')
four = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade4/cascade.xml')
five = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade5/cascade.xml')
six = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade6/cascade.xml')
seven = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade7/cascade.xml')
eight = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade8/cascade.xml')
nine = cv2.CascadeClassifier('data/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade9/cascade.xml')
gray = np.array(data['sequences'][0]).astype(np.float32)
gray = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
#gray = cv2.cvtColor(img, cv2.CV_RGB2GRAY)

zeros = zero.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
ones = one.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
twos = two.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
threes = three.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
fours = four.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
fives = five.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
sixes = size.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
sevens = seven.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
eights = eight.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
nines = nine.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)

不幸的是,这只会导致以下错误:

Traceback (most recent call last):
  File "digit_cascade.py", line 22, in <module>
    zeros = zero.detectMultiScale(gray, 1.3, 5, scaleFactor=0.6)
SystemError: error return without exception set

有人熟悉如何将原始 numpy 数组加载到 OpenCV detectMultiscale 中吗?

以下是我的一些不确定性:

  • OpenCV docs 有两个不同的detectMultiscale 签名。第一个的目的是什么,带有rejectLevelslevelWeights 的参数?
  • 我的图像是 112x112。此图像中的每个数字大约为 11x11 像素。级联尺寸为 20x30。我应该/我需要设置什么参数才能使级联正常工作?

系统信息:

cv2.__version__ # '2.4.11'
sys.version #'2.7.12 |Anaconda 4.2.0 (x86_64)| (default, Jul  2 2016, 17:43:17) \n[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)]'

【问题讨论】:

  • 这是一个相当奇怪的错误消息,我希望得到一些有意义的异常(或断言)消息。那是什么版本的 OpenCV?什么蟒蛇?什么平台? XML 是否正确加载? (zeros.empty()的结果是什么?)
  • @DanMašek 更新了版本。似乎级联加载正确。 zero.empty() # False.

标签: python opencv numpy


【解决方案1】:

我可以使用相同的级联文件运行分类器,同时直接从图像加载数据:

import numpy as np
import cv2

workspace = '/path/to/directory'

# cascades
cascades = [
    (cv2.CascadeClassifier(workspace + '/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade1/cascade.xml'), (255, 0, 0)),
    (cv2.CascadeClassifier(workspace + '/Google-Street-View-House-Numbers-Digit-Localization/cascades/cascade6/cascade.xml'), (0, 255, 0))
]

# input
img = cv2.imread('/path/to/image/house-number-16.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# detect and mark
for cascade, color in cascades:
    digits = cascade.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in digits:
        cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
        roi_gray = gray[y:y + h, x:x + w]
        roi_color = img[y:y + h, x:x + w]

# show result
cv2.imshow('img', img)
cv2.waitKey()

结果(虽然检测不到“1”):

我怀疑您的问题在于您从 pickle 保存图像的方式或加载它们的方式。

例如,默认情况下cv2.imread 将图像读取为整数numpy.ndarray。当我将其更改为浮点数(例如除以 255)时,出现错误:

OpenCV 错误:断言失败 (scaleFactor > 1 && image.depth() == CV_8U) 在detectMultiScale,文件 /home/yohanesgultom/opencv/modules/objdetect/src/cascadedetect.cpp, 第 1081 行 Traceback(最近一次调用最后一次):文件“cascade.py”,行 21,在 数字 = cascade.detectMultiScale(gray, 1.3, 5) cv2.error: /home/yohanesgultom/opencv/modules/objdetect/src/cascadedetect.cpp:1081: 错误:(-215) scaleFactor > 1 && image.depth() == CV_8U in function 检测多尺度

我在 Ubuntu 上运行它:

>>> cv2.__version__
'2.4.13'
>>> sys.version
'2.7.10 (default, Oct 14 2015, 16:09:02) \n[GCC 5.2.1 20151010]'

【讨论】:

  • 对,正如我在帖子中所说,我正在以二进制格式加载这些图像,即作为 numpy 数组。昨晚没有意识到这一点,我感到很愚蠢,但是因为我的二进制图像已经是单通道(即灰度),所以没有必要打电话给cvtColor。只需 gray = np.array(data['sequences'][0]).astype(np.uint8) 并以 one.detectMultiScale(gray, 1.3, 5) 的形式馈送到级联即可。将其留在这里以防其他人需要更多说明:answers.opencv.org/question/131606/… 谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-28
  • 2011-09-07
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多