I'm using a trained opencv cascade classifier to detect hands in video frames, and would like to lower my false positive rate.
Reading up on the net, I saw you can do so by accessing the
rejectLevels
and levelWeights
information returned by the detectMultiScale method. I saw here that this is possible in C++, my question is- has anyone managed to do it in Python? A similar question was asked here but it was for an earlier version of of the detection method.
If it is possible, what is the proper syntax to call the method? If it worked for you, please mention the OpenCV version you're using. I'm on 2.4.9.
The 2.4.11 API gives the following syntax
Python: cv2.CascadeClassifier.detectMultiScale(image, rejectLevels, levelWeights[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize[, outputRejectLevels]]]]]])
So accordingly, I've tried
import cv2
import cv2.cv as cv
import time
hand_cascade = cv2.CascadeClassifier('cascade.xml')
img = cv2.imread('test.jpg')
rejectLevels = []
levelWeights = []
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = hand_cascade.detectMultiScale(gray,rejectLevels,levelWeights, 1.1, 5,cv.CV_HAAR_FIND_BIGGEST_OBJECT,(30, 30),(100,100),True)
But the output I get is
[[259 101 43 43]
[354 217 43 43]
[240 189 43 43]
[316 182 47 47]
[277 139 92 92]]
[]
[]
Thanks for the help,
Ronen
detectMultiScale function is used to detect the faces. This function will return a rectangle with coordinates(x,y,w,h) around the detected face. It takes 3 common arguments — the input image, scaleFactor, and minNeighbours. scaleFactor specifies how much the image size is reduced with each scale.
Here is a list of the most common parameters of the detectMultiScale function : scaleFactor : Parameter specifying how much the image size is reduced at each image scale. minNeighbors : Parameter specifying how many neighbors each candidate rectangle should have to retain it. minSize : Minimum possible object size.
It is a machine learning based approach where a cascade function is trained from a lot of positive and negative images. It is then used to detect objects in other images.
detectMultiScale(gray, 1.3, 5) MultiScale detects objects of different sizes in the input image and returns rectangles positioned on the faces.
For anyone coming to this question and using OpenCV 3.0 I worked out after poking around the python API.
On the cascade classifier there are three methods detectMultiScale
, detectMultiScale2
, and detectMultiScale3
. Using the third one, I was able to get what looked like a confidence/weight.
faces = faceCascade.detectMultiScale3(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.CASCADE_SCALE_IMAGE,
outputRejectLevels = True
)
rects = faces[0]
neighbours = faces[1]
weights = faces[2]
weights[i]
looks to match the confidence of the face defined by rects[i]
. neighbours[i]
is the number of matches in neighbourhood of the current rectangle.
Short of hacking the c++, it doesn't look like there's any way to get the actual rejectLevels and levelWeights.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With