Ask Your Question

Revision history [back]

Possible cornerSubPix bug in 2.4.13

Hi, I'm using OpenCV 2.4.13 on OSX, and I'm calling cv2.cornerSubPix to refine the location of some corners, and generally its working, but in some cases it seems to return the wrong value completely.

In this example, the refined corner is actually on the corner of the specified search window, which seems like a hint, that maybe the search was exhausted and it just returned the last spot it searched?

Here is the input file test.jpg: test.jpg

Here is the output output.png In the output, the cyan crosshair is the original point, quite close to the corner, the purple crosshair is what comes out of cv2.cornerSubPix. If I was to draw the search window on the image (8,8) centered around the cyan crosshair, the purple cross hair would be on the top left corner of that box.

image description

Here is my code:

import numpy as np
import cv2
import math

def draw_crosshair(img, pt, color):
  # Use `shift` to try to gain sub-pixel accuracy
  shift = 10
  m = math.pow(2, shift)

  pt = (int(pt[0] * m), int(pt[1] * m))

  size = int(10 * m)
  gap = int(4 * m)
  cv2.line(img, (pt[0], pt[1]-size), (pt[0], pt[1]-gap), color, 1, shift=shift)
  cv2.line(img, (pt[0], pt[1]+gap), (pt[0], pt[1]+size), color, 1, shift=shift)
  cv2.line(img, (pt[0]-size, pt[1]), (pt[0]-gap, pt[1]), color, 1, shift=shift)
  cv2.line(img, (pt[0]+gap, pt[1]), (pt[0]+size, pt[1]), color, 1, shift=shift)
  cv2.line(img, pt, pt, color, 1, shift=shift)

img = cv2.imread("./test.jpg", cv2.IMREAD_GRAYSCALE)
assert(img is not None)
epsilon = 0.05
iteration_count = 11
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, iteration_count, epsilon)
window_size = (8, 8)

pt = [581.61376953, 400.81665039]
corners = np.float32([[pt]])
cv2.cornerSubPix(img, corners, window_size, None, term_crit)

print "orig", pt                    # [ 581.61376953  400.81665039] 
print "new", corners[0][0]   # [ 573.89221191  393.37179565]

# convert to color for crosshairs
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

draw_crosshair(img, pt, (255,255,0))
draw_crosshair(img, corners[0][0], (255,0,255))

cv2.imshow('result', img)
raw_input("Press any key to continue...")