1
votes

I'm having a hard time to make this work. My image set is made of small images (58x65).

I'm using ORB with the following parameters:

# Initiate ORB detector
# default: ORB(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31, int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31)
orb = cv2.ORB_create(
  nfeatures = 500,                    # The maximum number of features to retain.
  scaleFactor = 1.2,                  # Pyramid decimation ratio, greater than 1
  nlevels = 8,                        # The number of pyramid levels.
  edgeThreshold = 7,                  # This is size of the border where the features are not detected. It should roughly match the patchSize parameter
  firstLevel = 0,                     # It should be 0 in the current implementation.
  WTA_K = 2,                          # The number of points that produce each element of the oriented BRIEF descriptor.
  scoreType = cv2.ORB_HARRIS_SCORE,   # The default HARRIS_SCORE means that Harris algorithm is used to rank features (the score is written to KeyPoint::score and is 
                                      # used to retain best nfeatures features); FAST_SCORE is alternative value of the parameter that produces slightly less stable 
                                      # keypoints, but it is a little faster to compute.
  #scoreType = cv2.ORB_FAST_SCORE,
  patchSize = 7                       # size of the patch used by the oriented BRIEF descriptor. Of course, on smaller pyramid layers the perceived image area covered
                                      # by a feature will be larger.
)

As it can be seen I changed edgeThreshold and patchSize parameters, but I'm afraid these sizes are too small to find meaningful features.

I am testing with a pretty big set of parking lot images (~3900 images of 58x65), both empty and occupied.

But the results are not consistent: an image of a car parked (from out of the set) is shown as closer to empty spaces than other cars parked.

What could I have been doing wrong? My guess is the above mentioned parameters. Someone with more experience on the subject could confirm it?

Edit:

Here is a small subset of the images.

Full dataset can be found here.

1
Are you trying to build a car classifier with ORB feature detector? ORB features are low level features and simply finding similar features from a training set won't work very well, as you've figured by now.zteffi
Not a car classifier (identify a Honda, Nissan, Ford, etc) but a parking lot space identifier (empty vs occupied)André Baptista
Can you show some images (empty and occupied) ? Maybe with ORB detection materialized ?xiawi
Just updated the question with links for a sample of images and full datasetAndré Baptista

1 Answers

4
votes

ORB and small images are not typically seen together because of the window size of the detector and number of scales. Your window size is 7 x 7, the number of scales you chose is 8 with a scaling factor of 1.2. This is around the typical settings for the detector but if you do the math, you'll quickly realize that as you go down further scales the window size will be too large, prompting very few detections if any. I would not recommend you use ORB here.

Try using a dense feature descriptor, such as HOG or Dense SIFT which provides a feature descriptor for overlapping windows of pixels regardless of their composition. Judging from the images that you've described, this sounds like a better approach.

Assuming you have a grayscale image called im, for HOG:

import cv2

sample = ... # Path to image here

# Create HOG Descriptor object
hog = cv2.HOGDescriptor()

im = cv2.imread(sample, 0) # Grayscale image

# Compute HOG descriptor
h = hog.compute(im)

For Dense SIFT:

import cv2

sample = ... # Path to image here

im = cv2.imread(sample, 0) # Grayscale image

# Create SIFT object
sift = cv2.xfeatures2d.SIFT_create()

# Provide a list of keypoints in spaces of 5 pixels horizontally and vertically
# Change the step size according to what you want
step_size = 5
kp = [cv2.KeyPoint(x, y, step_size) for y in range(0, img.shape[0], step_size) 
                                    for x in range(0, img.shape[1], step_size)]

# Calculate Dense SIFT feature vector
dense_feat = sift.compute(img, kp)

Note that for the SIFT descriptor, you will need to install the opencv-contrib-python flavour of the library (i.e. pip install opencv-contrib-python).