Ask Your Question
0

Load Single Channel Numpy Array Image with detectMultiScale

asked 2017-03-06 22:26:18 -0600

Eric H gravatar image

I have sequences of digits originally from Mnist data set that I've manipulated with OpenCV. They are saved in a pickle file. They are 1 channel images with shape (112, 112).

I want to run these through an OpenCV Cascade Classifier, similar to docs.opencv.org/trunk/d7/d8b/tutorial_py_face_detection.html, but instead with these github.com/ankitdhall/Google-Street-View-House-Numbers-Digit-Localization.

Here is my attempt:

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)

Unfortunately this just results in the following error:

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

Is anyone familiar with how to load raw numpy arrays into OpenCV detectMultiscale?

Here are some uncertainties I have:

  • The OpenCV docs docs.opencv.org/2.4/modules/objdetect/doc/cascade_classification.html#cascadeclassifier-detectmultiscale have two different signatures for detectMultiscale. What is the purpose of the first, with the arguments for rejectLevels and levelWeights?
  • My images are 112x112. Each digit within this image would be around 11x11 pixels. The cascade sizes are 20x30. What parameter should I/ do I need to set in order for the cascades to work properly?

(this is a repost from SO).

edit retag flag offensive close merge delete

Comments

All the comments below were already given on your issue at github ... in principle people first try the suggestions before opening just a new question ;)

StevenPuttemans gravatar imageStevenPuttemans ( 2017-03-07 09:02:36 -0600 )edit
1

Thanks @StevenPuttemans not sure whether I would get a response here - I posted them at once. I definitely appreciate all of the suggestions.

Eric H gravatar imageEric H ( 2017-03-07 09:54:18 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2017-03-07 00:59:46 -0600

berak gravatar image

updated 2017-03-07 01:11:10 -0600

the signature for detectMultiScale is this:

detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) -> objects

so your usage is wrong, you have scaleFactor 2 times, and that must be > 1.0, too !

then, please convert your gray image to np.uint8, not to np.float32.

(CascadeClassifier needs uchar data as input, while for a neural network, you'd use floats)

also, please check, if your cascades were loaded correctly, like:

if zero.empty(): raise BadData()

Each digit within this image would be around 11x11 pixels. The cascade sizes are 20x30.

so, 20x30 is the minimum size , that can be detected. this means, you have to upscale your images by a factor of 3 or 4.

last, but not least - imho the attempt at using 10 cascades to detect numbers is kinda a rotten idea. how do you plan to deal with multiple, conflicting false predictions ? it will also take ages to process. good luck with that !

edit flag offensive delete link more

Comments

Thanks. My most obvious error was also calling cvtColor on a numpy array (112, 112), which is already single channel gray-scale image.

PS I'm trying to solve the address number street view problem. I want to get digit bboxes from an image. Do you any resources for a better approach at solving the problem. Maybe create a cascade classifier for any digit, then run resized cropped images of those individual digits through a classifier that's been trained on digits 0-9?

Eric H gravatar imageEric H ( 2017-03-07 20:51:57 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-03-06 22:26:18 -0600

Seen: 618 times

Last updated: Mar 07 '17