Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
668 views
in Technique[技术] by (71.8m points)

python - How to use ORB feature detector with small images in OpenCV

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...