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.
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)
cv2.waitKey(1)
raw_input("Press any key to continue...")
Hmm, I'm now realizing that perhaps the search window is including part of the black from the outer circle, and its finding that as the corner...?