def extract_chessboards(img, include_unrefined=False, use_corner_thresholding=True): if img.shape[1] > 4000: scale_factor = .2 elif img.shape[1] > 2000: scale_factor = .5 else: scale_factor = 1 if scale_factor < 1: img_scaled = imresize(img, scale_factor, interp='bicubic') else: img_scaled = img corners, v1, v2 = find_corners(img_scaled, use_corner_thresholding=use_corner_thresholding) chessboards = chessboards_from_corners(corners, v1, v2) chessboards = fix_orientations(chessboards, corners, img_scaled) if scale_factor < 1: corners = np.round(corners * (1.0/scale_factor)).astype(np.int) img = prepare_image(img) du, dv, angle, weight = c_pycb.gradient(img) refined, v1, v2 = do_refine_corners(du, dv, angle, weight, corners, 15) else: refined = corners if include_unrefined: return refined, chessboards, corners else: return refined, chessboards
def extract_chessboards(img, include_unrefined=False, use_corner_thresholding=True): if img.shape[1] > 4000: scale_factor = .2 elif img.shape[1] > 2000: scale_factor = .5 else: scale_factor = 1 if scale_factor < 1: img_scaled = imresize(img, scale_factor, interp='bicubic') else: img_scaled = img corners, v1, v2 = find_corners( img_scaled, use_corner_thresholding=use_corner_thresholding) chessboards = chessboards_from_corners(corners, v1, v2) chessboards = fix_orientations(chessboards, corners, img_scaled) if scale_factor < 1: corners = np.round(corners * (1.0 / scale_factor)).astype(np.int) img = prepare_image(img) du, dv, angle, weight = c_pycb.gradient(img) refined, v1, v2 = do_refine_corners(du, dv, angle, weight, corners, 15) else: refined = corners if include_unrefined: return refined, chessboards, corners else: return refined, chessboards
def find_corners(img, tau=0.001, refine_corners=True, use_corner_thresholding=False): img = prepare_image(img) # Use a shared variable so we aren't copying the image each time we use it #img_theano = theano.shared(img) height, width = img.shape du, dv, angle, weight = c_pycb.gradient(img)#, img_theano) # scale input image min = np.min(img) max = np.max(img) img = (img-min)/(max-min) radius = [4, 8, 12] # template properties template_props = [ [ 0, pi/2, radius[0]], [pi/4, -pi/4, radius[0]], [ 0, pi/2, radius[1]], [pi/4, -pi/4, radius[1]], [ 0, pi/2, radius[2]], [pi/4, -pi/4, radius[2]], ] # Filter image corners_img = np.zeros(img.shape) for template_params in template_props: template = c_pycb.Template(*template_params) ## Batch filters for speed #filters = np.empty((4, template.a1.shape[0], template.a1.shape[1]),dtype=template.a1.dtype) #filters[0,:,:] = template.a1 #filters[1,:,:] = template.a2 #filters[2,:,:] = template.b1 #filters[3,:,:] = template.b2 #s = theano_conv2d(img_theano, filters, border_mode='full').eval() ## Take off padding #r = template_params[2] #corners_a1_2 = s[0, r:height+r,r:width+r] #corners_a2_2 = s[1, r:height+r,r:width+r] #corners_b1_2 = s[2, r:height+r,r:width+r] #corners_b2_2 = s[3, r:height+r,r:width+r] #template = c_pycb.Template(*template_params) vectorize = True if vectorize: cur_func = None if template.a1.shape[0] == 9: cur_func = tconv_9 elif template.a1.shape[0] == 17: cur_func = tconv_17 elif template.a1.shape[0] == 25: cur_func = tconv_25 template.a1 = template.a1[None, :][None, :] template.a2 = template.a2[None, :][None, :] template.b1 = template.b1[None, :][None, :] template.b2 = template.b2[None, :][None, :] filts = np.concatenate((template.a1, template.a2, template.b1, template.b2), axis=0).astype("float32") valz = cur_func(img.astype("float32")[None, :][None, :], filts) corners_a1 = valz[0, 0] corners_a2 = valz[0, 1] corners_b1 = valz[0, 2] corners_b2 = valz[0, 3] else: corners_a1, corners_a2, corners_b1, corners_b2 = c_pycb.conv_template( img, template.a1, template.a2, template.b1, template.b2) # print " " + str(template.a1.shape) # print " " + str(template.a2.shape) # print " " + str(template.b1.shape) # print " " + str(template.b2.shape) #corners_a1 = c_pycb.conv2(img, template.a1) #corners_a2 = c_pycb.conv2(img, template.a2) #corners_b1 = c_pycb.conv2(img, template.b1) #corners_b2 = c_pycb.conv2(img, template.b2) #corners_a1_3 = convolve2d(img, template.a1, mode='same') #import pdb; pdb.set_trace() #print corners_a1, corners_a2, corners_b1, corners_b2 #corners_a1 = convolve2d(img, template.a1, mode='same') #corners_a2 = convolve2d(img, template.a2, mode='same') #corners_b1 = convolve2d(img, template.b1, mode='same') #corners_b2 = convolve2d(img, template.b2, mode='same') # Compute mean corners_mu = (corners_a1 + corners_a2 + corners_b1 + corners_b2)/4 # case 1: a=white, b=black corners_a = np.minimum(corners_a1 - corners_mu,corners_a2 - corners_mu) corners_b = np.minimum(corners_mu - corners_b1,corners_mu - corners_b2) corners_1 = np.minimum(corners_a,corners_b) # case 2: b=white, a=black corners_a = np.minimum(corners_mu - corners_a1, corners_mu - corners_a2) corners_b = np.minimum(corners_b1 - corners_mu, corners_b2 - corners_mu) corners_2 = np.minimum(corners_a, corners_b) # update corner map corners_img = np.maximum(corners_img, corners_1) corners_img = np.maximum(corners_img, corners_2) # extract corner candidates via non maximum suppression corners = c_pycb.non_maximum_supression(corners_img,3,0.025,5) # subpixel refinement if refine_corners: corners, v1, v2 = do_refine_corners(du,dv,angle,weight,corners,10) if len(corners) == 0: return corners, v1, v2 # remove corners without edges idx = np.where((v1[:,0]==0) & (v1[:,1]==0))[0] corners = np.delete(corners, idx, 0) v1 = np.delete(v1, idx, 0) v2 = np.delete(v2, idx, 0) if len(corners) == 0: return corners, v1, v2 if use_corner_thresholding: #% score corners scores = score_corners(img,angle,weight,corners,v1,v2,radius) # remove low scoring corners idx = np.where(scores<tau) corners = np.delete(corners, idx, 0) v1 = np.delete(v1, idx, 0) v2 = np.delete(v2, idx, 0) scores = np.delete(scores, idx, 0) # make v1(:,1)+v1(:,2) positive (=> comparable to c++ code) idx = np.where((v1[:,0]+v1[:,1])<0)[0] if len(idx) > 0: v1[idx,:] = -v1[idx,:] # make all coordinate systems right-handed (reduces matching ambiguities from 8 to 4) corners_n1 = np.column_stack([v1[:,1], -v1[:,0]]) flip = -np.sign(corners_n1[:,0]*v2[:,0]+corners_n1[:,1]*v2[:,1]) v2 = v2*flip[:,np.newaxis].dot(np.ones((1,2))) return corners, v1, v2
def find_corners(img, tau=0.001, refine_corners=True, use_corner_thresholding=False): img = prepare_image(img) # Use a shared variable so we aren't copying the image each time we use it #img_theano = theano.shared(img) height, width = img.shape du, dv, angle, weight = c_pycb.gradient(img) #, img_theano) # scale input image min = np.min(img) max = np.max(img) img = (img - min) / (max - min) radius = [4, 8, 12] # template properties template_props = [ [0, pi / 2, radius[0]], [pi / 4, -pi / 4, radius[0]], [0, pi / 2, radius[1]], [pi / 4, -pi / 4, radius[1]], [0, pi / 2, radius[2]], [pi / 4, -pi / 4, radius[2]], ] # Filter image corners_img = np.zeros(img.shape) for template_params in template_props: template = c_pycb.Template(*template_params) ## Batch filters for speed #filters = np.empty((4, template.a1.shape[0], template.a1.shape[1]),dtype=template.a1.dtype) #filters[0,:,:] = template.a1 #filters[1,:,:] = template.a2 #filters[2,:,:] = template.b1 #filters[3,:,:] = template.b2 #s = theano_conv2d(img_theano, filters, border_mode='full').eval() ## Take off padding #r = template_params[2] #corners_a1_2 = s[0, r:height+r,r:width+r] #corners_a2_2 = s[1, r:height+r,r:width+r] #corners_b1_2 = s[2, r:height+r,r:width+r] #corners_b2_2 = s[3, r:height+r,r:width+r] #template = c_pycb.Template(*template_params) vectorize = True if vectorize: cur_func = None if template.a1.shape[0] == 9: cur_func = tconv_9 elif template.a1.shape[0] == 17: cur_func = tconv_17 elif template.a1.shape[0] == 25: cur_func = tconv_25 template.a1 = template.a1[None, :][None, :] template.a2 = template.a2[None, :][None, :] template.b1 = template.b1[None, :][None, :] template.b2 = template.b2[None, :][None, :] filts = np.concatenate( (template.a1, template.a2, template.b1, template.b2), axis=0).astype("float32") valz = cur_func(img.astype("float32")[None, :][None, :], filts) corners_a1 = valz[0, 0] corners_a2 = valz[0, 1] corners_b1 = valz[0, 2] corners_b2 = valz[0, 3] else: corners_a1, corners_a2, corners_b1, corners_b2 = c_pycb.conv_template( img, template.a1, template.a2, template.b1, template.b2) # print " " + str(template.a1.shape) # print " " + str(template.a2.shape) # print " " + str(template.b1.shape) # print " " + str(template.b2.shape) #corners_a1 = c_pycb.conv2(img, template.a1) #corners_a2 = c_pycb.conv2(img, template.a2) #corners_b1 = c_pycb.conv2(img, template.b1) #corners_b2 = c_pycb.conv2(img, template.b2) #corners_a1_3 = convolve2d(img, template.a1, mode='same') #import pdb; pdb.set_trace() #print corners_a1, corners_a2, corners_b1, corners_b2 #corners_a1 = convolve2d(img, template.a1, mode='same') #corners_a2 = convolve2d(img, template.a2, mode='same') #corners_b1 = convolve2d(img, template.b1, mode='same') #corners_b2 = convolve2d(img, template.b2, mode='same') # Compute mean corners_mu = (corners_a1 + corners_a2 + corners_b1 + corners_b2) / 4 # case 1: a=white, b=black corners_a = np.minimum(corners_a1 - corners_mu, corners_a2 - corners_mu) corners_b = np.minimum(corners_mu - corners_b1, corners_mu - corners_b2) corners_1 = np.minimum(corners_a, corners_b) # case 2: b=white, a=black corners_a = np.minimum(corners_mu - corners_a1, corners_mu - corners_a2) corners_b = np.minimum(corners_b1 - corners_mu, corners_b2 - corners_mu) corners_2 = np.minimum(corners_a, corners_b) # update corner map corners_img = np.maximum(corners_img, corners_1) corners_img = np.maximum(corners_img, corners_2) # extract corner candidates via non maximum suppression corners = c_pycb.non_maximum_supression(corners_img, 3, 0.025, 5) # subpixel refinement if refine_corners: corners, v1, v2 = do_refine_corners(du, dv, angle, weight, corners, 10) if len(corners) == 0: return corners, v1, v2 # remove corners without edges idx = np.where((v1[:, 0] == 0) & (v1[:, 1] == 0))[0] corners = np.delete(corners, idx, 0) v1 = np.delete(v1, idx, 0) v2 = np.delete(v2, idx, 0) if len(corners) == 0: return corners, v1, v2 if use_corner_thresholding: #% score corners scores = score_corners(img, angle, weight, corners, v1, v2, radius) # remove low scoring corners idx = np.where(scores < tau) corners = np.delete(corners, idx, 0) v1 = np.delete(v1, idx, 0) v2 = np.delete(v2, idx, 0) scores = np.delete(scores, idx, 0) # make v1(:,1)+v1(:,2) positive (=> comparable to c++ code) idx = np.where((v1[:, 0] + v1[:, 1]) < 0)[0] if len(idx) > 0: v1[idx, :] = -v1[idx, :] # make all coordinate systems right-handed (reduces matching ambiguities from 8 to 4) corners_n1 = np.column_stack([v1[:, 1], -v1[:, 0]]) flip = -np.sign(corners_n1[:, 0] * v2[:, 0] + corners_n1[:, 1] * v2[:, 1]) v2 = v2 * flip[:, np.newaxis].dot(np.ones((1, 2))) return corners, v1, v2