def show_keypoints(rchip, kpts, draw_ell=True, draw_pts=False, sel_fx=None, fnum=0, pnum=None, color=None, rect=False, **kwargs): df2.imshow(rchip, fnum=fnum, pnum=pnum, **kwargs) _annotate_kpts(kpts, sel_fx, draw_ell, draw_pts, color=color, rect=rect) ax = df2.gca() ax._hs_viewtype = 'keypoints' ax._hs_kpts = kpts
def _draw_chip(title, chip, px, *args, **kwargs): df2.imshow(chip, *args, title=title, fnum=fnum, pnum=(3, 4, px), **kwargs)
def test(): (hs, qcx, cx, fm, fs, rchip1, rchip2, kpts1, kpts2) = ld2.get_sv_test_data() # READ IMAGE AND ROI cx2_roi = hs.tables.cx2_roi cx2_gx = hs.tables.cx2_gx gx2_gname = hs.tables.gx2_gname #--- roi = cx2_roi[cx] gx = cx2_gx[cx] img_fname = gx2_gname[gx] img_path = os.path.join(hs.dirs.img_dir, img_fname) #--- #print('Showing Input') ## Original Image #df2.imshow(mask_input, fignum=1, plotnum=122) #df2.present() # Crop out chips #chip = img[ry:(ry+rh), rx:(rx+rw)] #chip_mask = mask[ry:(ry+rh), rx:(rx+rw)] # IMAGE AND MASK #df2.imshow(img, plotnum=121, fignum=2, doclf=True) #df2.imshow(mask, plotnum=122, fignum=2) # MASKED CHIP #df2.figure(fignum=3, doclf=True) #df2.imshow(chip, plotnum=131, fignum=3, doclf=True) #df2.imshow(color_mask, plotnum=132, fignum=3) #df2.imshow(seg_chip, plotnum=133, fignum=3) seg_chip = segment(img_path, roi) df2.show_img(hs, cx, fignum=1, plotnum=121, title='original', doclf=True) df2.imshow(seg_chip, fignum=1, plotnum=122, title='segmented') df2.present()
def draw_splash(self): print('[back] draw_splash()') img = imread('_frontend/splash.png') fig = df2.figure() print(fig) print(fig is self.win.plotWidget.figure) df2.imshow(img) df2.update()
def show_chipres(hs, res, cx, fnum=None, pnum=None, sel_fm=[], in_image=False, **kwargs): 'shows single annotated match result.' qcx = res.qcx #cx2_score = res.get_cx2_score() cx2_fm = res.get_cx2_fm() cx2_fs = res.get_cx2_fs() #cx2_fk = res.get_cx2_fk() #printDBG('[viz.show_chipres()] Showing matches from %s' % (vs_str)) #printDBG('[viz.show_chipres()] fnum=%r, pnum=%r' % (fnum, pnum)) # Test valid cx printDBG('[viz] show_chipres()') if np.isnan(cx): nan_img = np.zeros((32, 32), dtype=np.uint8) title = '(q%s v %r)' % (hs.cidstr(qcx), cx) df2.imshow(nan_img, fnum=fnum, pnum=pnum, title=title) return fm = cx2_fm[cx] fs = cx2_fs[cx] #fk = cx2_fk[cx] #vs_str = hs.vs_str(qcx, cx) # Read query and result info (chips, names, ...) if in_image: # TODO: rectify build_transform2 with cc2 # clean up so its not abysmal rchip1, rchip2 = [hs.cx2_image(_) for _ in [qcx, cx]] kpts1, kpts2 = cx2_imgkpts(hs, [qcx, cx]) else: rchip1, rchip2 = hs.get_chip([qcx, cx]) kpts1, kpts2 = hs.get_kpts([qcx, cx]) # Build annotation strings / colors lbl1 = 'q' + hs.cidstr(qcx) lbl2 = hs.cidstr(cx) if in_image: # HACK! lbl1 = None lbl2 = None # Draws the chips and keypoint matches kwargs_ = dict(fs=fs, lbl1=lbl1, lbl2=lbl2, fnum=fnum, pnum=pnum, vert=hs.prefs.display_cfg.vert) kwargs_.update(kwargs) ax, xywh1, xywh2 = df2.show_chipmatch2(rchip1, rchip2, kpts1, kpts2, fm, **kwargs_) x1, y1, w1, h1 = xywh1 x2, y2, w2, h2 = xywh2 if len(sel_fm) > 0: # Draw any selected matches _smargs = dict(rect=True, colors=df2.BLUE) df2.draw_fmatch(xywh1, xywh2, kpts1, kpts2, sel_fm, **_smargs) offset1 = (x1, y1) offset2 = (x2, y2) annotate_chipres(hs, res, cx, xywh2=xywh2, in_image=in_image, offset1=offset1, offset2=offset2, **kwargs) return ax, xywh1, xywh2
def segment(img_path, roi): img = cv2.imread(img_path) # Grab cut parametrs (w, h) = img.shape[:2] [rx, ry, rw, rh] = roi expand = 10 rect = (rx - expand, rw + expand, ry - expand, rh + expand) mask_input = np.zeros((w, h), dtype=np.uint8) bg_model = np.zeros((1, 13 * 5)) fg_model = np.zeros((1, 13 * 5)) num_iters = 5 # Make mask specify the ROI mask_input[ry:(ry + rh), rx:(rx + rw)] = cv2.GC_PR_FGD grabcut_mode = cv2.GC_INIT_WITH_MASK # Do grab cut (mask, bg_model, fg_model) = cv2.grabCut(img, mask_input, rect, bg_model, fg_model, num_iters, mode=grabcut_mode) # Make the segmented chip # Normalize mask mask = np.array(mask, np.float64) mask[mask == cv2.GC_BGD] = 0 #.1 mask[mask == cv2.GC_PR_BGD] = 0 #.25 mask[mask == cv2.GC_PR_FGD] = 1 #.75 mask[mask == cv2.GC_FGD] = 1 # Clean the mask element = cv2.getStructuringElement(cv2.MORPH_CROSS, (10, 10)) tmp_ = mask tmp_ = cv2.erode(tmp_, element) tmp_ = cv2.dilate(tmp_, element) tmp_ = cv2.dilate(tmp_, element) tmp_ = cv2.dilate(tmp_, element) df2.imshow(tmp_) df2.update() mask = tmp_ # Reshape chip_mask to NxMx3 color_mask = np.tile(chip_mask.reshape(tuple(list(chip_mask.shape) + [1])), (1, 1, 3)) seg_chip = np.array(chip, dtype=np.float) * color_mask seg_chip = np.array(np.round(seg_chip), dtype=np.uint8) return seg_chip
def segment(img_path, roi): img = cv2.imread(img_path) # Grab cut parametrs (w, h) = img.shape[:2] [rx, ry, rw, rh] = roi expand = 10 rect = (rx-expand, rw+expand, ry-expand, rh+expand) mask_input = np.zeros((w,h), dtype=np.uint8) bg_model = np.zeros((1, 13 * 5)) fg_model = np.zeros((1, 13 * 5)) num_iters = 5 # Make mask specify the ROI mask_input[ry:(ry+rh), rx:(rx+rw)] = cv2.GC_PR_FGD grabcut_mode = cv2.GC_INIT_WITH_MASK # Do grab cut (mask, bg_model, fg_model) = cv2.grabCut(img, mask_input, rect, bg_model, fg_model, num_iters, mode=grabcut_mode) # Make the segmented chip # Normalize mask mask = np.array(mask, np.float64) mask[mask == cv2.GC_BGD] = 0#.1 mask[mask == cv2.GC_PR_BGD] = 0#.25 mask[mask == cv2.GC_PR_FGD] = 1#.75 mask[mask == cv2.GC_FGD] = 1 # Clean the mask element = cv2.getStructuringElement(cv2.MORPH_CROSS,(10,10)) tmp_ = mask tmp_ = cv2.erode(tmp_, element) tmp_ = cv2.dilate(tmp_, element) tmp_ = cv2.dilate(tmp_, element) tmp_ = cv2.dilate(tmp_, element) df2.imshow(tmp_); df2.update() mask = tmp_ # Reshape chip_mask to NxMx3 color_mask = np.tile(chip_mask.reshape(tuple(list(chip_mask.shape)+[1])), (1, 1, 3)) seg_chip = np.array(chip, dtype=np.float) * color_mask seg_chip = np.array(np.round(seg_chip), dtype=np.uint8) return seg_chip
def show_image(hs, gx, sel_cxs=[], fnum=1, figtitle='Img', annote=True, draw_lbls=True, **kwargs): # Shows an image with annotations gname = hs.tables.gx2_gname[gx] title = 'gx=%r gname=%r' % (gx, gname) img = hs.gx2_image(gx) fig = df2.figure(fnum=fnum, docla=True) fig, ax = df2.imshow(img, title=title, fnum=fnum, **kwargs) ax._hs_viewtype = 'image' _annotate_image(hs, ax, gx, sel_cxs, draw_lbls, annote) df2.set_figtitle(figtitle)
def show_chip(hs, cx=None, allres=None, res=None, draw_ell=True, draw_pts=False, nRandKpts=None, prefix='', sel_fx=None, color=None, in_image=False, sel_fx2=None, **kwargs): printDBG('[viz] show_chip()') if allres is not None: res = allres.qcx2_res[cx] if res is not None: cx = res.qcx if in_image: rchip = hs.cx2_image(cx) else: rchip = kwargs['rchip'] if 'rchip' in kwargs else hs.get_chip(cx) # Add info to title title_list = [] title_list += [hs.cidstr(cx)] # FIXME #title_list += ['gname=%r' % hs.cx2_gname(cx)] title_list += ['name=%r' % hs.cx2_name(cx)] #title_list += [hs.num_indexed_gt_str(cx)] if NO_LABEL_OVERRIDE: title_str = '' else: title_str = prefix + ', '.join(title_list) fig, ax = df2.imshow(rchip, title=title_str, **kwargs) # Add user data to axis ax._hs_viewtype = 'chip' ax._hs_cx = cx if draw_ell or draw_pts: # FIXME if in_image: kpts = cx2_imgkpts(hs, [cx])[0] else: kpts = kwargs['kpts'] if 'kpts' in kwargs else hs.get_kpts(cx) if sel_fx2 is not None: sel_fx2 = np.array(sel_fx2) kpts = kpts[sel_fx2] if res is not None: # Draw keypoints with groundtruth information cx2_color = kwargs.get('cx2_color', None) _annotate_qcx_match_results(hs, res, cx, kpts, cx2_color) else: # Just draw boring keypoints _annotate_kpts(kpts, sel_fx, draw_ell, draw_pts, color, nRandKpts)
def plot_score_matrix(allres): print('[viz] plotting score matrix') score_matrix = allres.score_matrix title = 'Score Matrix\n' + allres.title_suffix # Find inliers #inliers = helpers.find_std_inliers(score_matrix) #max_inlier = score_matrix[inliers].max() # Trunate above 255 score_img = np.copy(score_matrix) #score_img[score_img < 0] = 0 #score_img[score_img > 255] = 255 #dim = 0 #score_img = helpers.norm_zero_one(score_img, dim=dim) # Make colors scores = score_img.flatten() colors = df2.scores_to_color(scores, logscale=True) cmap = df2.scores_to_cmap(scores, colors) df2.figure(fnum=FIGNUM, doclf=True, title=title) # Show score matrix df2.imshow(score_img, fnum=FIGNUM, cmap=cmap) # Colorbar df2.colorbar(scores, colors) df2.set_xlabel('database') df2.set_ylabel('queries')
def draw_keypoint_patch(rchip, kp, sift=None, warped=False, **kwargs): #print('--------------------') #print('[extract] Draw Patch') if warped: wpatch, wkp = get_warped_patch(rchip, kp) patch = wpatch subkp = wkp else: patch, subkp = get_patch(rchip, kp) #print('[extract] kp = '+str(kp)) #print('[extract] subkp = '+str(subkp)) #print('[extract] patch.shape = %r' % (patch.shape,)) color = (0, 0, 1) fig, ax = df2.imshow(patch, **kwargs) df2.draw_kpts2([subkp], ell_color=color, pts=True) if not sift is None: df2.draw_sift(sift, [subkp]) return ax
def test(hs, qcx): fx2_scale = sv2.keypoint_scale(hs.feats.cx2_kpts[qcx]) fx = fx2_scale.argsort()[::-1][40] rchip = hs.get_chip(qcx) kp = hs.feats.cx2_kpts[qcx][fx] # Show full image and keypoint df2.figure(fignum=9000, doclf=True) df2.imshow(rchip, plotnum=(1,3,1)) df2.draw_kpts2([kp], ell_color=(1,0,0), pts=True) # Show cropped image and keypoint patch, subkp = get_patch(rchip, kp) df2.imshow(patch, plotnum=(1,3,2)) df2.draw_kpts2([subkp], ell_color=(1,0,0), pts=True) # Show warped image and keypoint wpatch, wkp = get_warped_patch(rchip, kp) df2.imshow(wpatch, plotnum=(1,3,3)) df2.draw_kpts2([wkp], ell_color=(1,0,0), pts=True) # df2.set_figtitle('warp test')
def show_splash(fnum=1, **kwargs): #printDBG('[viz] show_splash()') splash_fpath = io.splash_img_fpath() img = io.imread(splash_fpath) df2.imshow(img, fnum=fnum, **kwargs)
def viz_top_features(hs, res, low, high, fignum=0, draw_chips=True): from collections import defaultdict qcx = res.qcx cx2_nx = hs.tables.cx2_nx top_patches_list = get_top_scoring_patches(hs, res, low, high) num_rows = high-low num_cols = 4 if params.__MATCH_TYPE__ == 'vsmany': num_cols = 6 # Initialize Figure fig = df2.figure(fignum+1, plotnum=(num_rows, num_cols,1)) cx2_rchip = defaultdict(int) cx2_kplist = defaultdict(list) def draw_one_kp(patch, kp, plotx, color, desc=None): fig, ax = df2.imshow(patch, plotnum=(num_rows, num_cols, plotx)) df2.draw_kpts2([kp], ell_color=color, pts=True) if not desc is None and not '--nodesc' in sys.argv: df2.draw_sift(desc, [kp]) df2.draw_border(ax, color, 1) for tx, (patches1, patches2, patchesN, cx, feat_score) in enumerate(top_patches_list): (kp1, subkp1, wkp1, patch1, wpatch1, cx1, desc1) = patches1 (kp2, subkp2, wkp2, patch2, wpatch2, cx2, desc2) = patches2 # draw on table # Draw Query Keypoint plotx = (tx*num_cols) draw_one_kp(patch1, subkp1, plotx+1, df2.GREEN, desc1) qnx = cx2_nx[qcx] df2.plt.gca().set_xlabel('qcx=%r; qnx=%r' % (qcx, qnx)) draw_one_kp(wpatch1, wkp1, plotx+2, df2.GREEN, desc1) # Draw ith < k match draw_one_kp(patch2, subkp2, plotx+3, df2.BLUE, desc2) nx = cx2_nx[cx] df2.plt.gca().set_xlabel('cx=%r; nx=%r' % (cx, nx)) draw_one_kp(wpatch2, wkp2, plotx+4, df2.BLUE, desc2) df2.plt.gca().set_xlabel('score=%r' % (feat_score)) # Draw k+1th match if params.__MATCH_TYPE__ == 'vsmany': (kpN, subkpN, wkpN, patchN, wpatchN, cxN, descN) = patchesN draw_one_kp(patchN, subkpN, plotx+5, df2.ORANGE, descN) nxN = cx2_nx[qcx] df2.plt.gca().set_xlabel('cxN=%r; nxN=%r' % (cxN, nxN)) draw_one_kp(wpatchN, wkpN, plotx+6, df2.ORANGE, descN) # Get other info cx2_rchip[cx] = hs.get_chip(cx) cx2_kplist[qcx].append(kp1) cx2_kplist[cx].append(kp2) # Draw annotations on df2.figure(plotnum=(num_rows, num_cols,1), title='Query Patch') df2.figure(plotnum=(num_rows, num_cols,2), title='Query Patch') df2.figure(plotnum=(num_rows, num_cols,3), title='Result Patch') df2.figure(plotnum=(num_rows, num_cols,4), title='Result Warped') if params.__MATCH_TYPE__ == 'vsmany': df2.figure(plotnum=(num_rows, num_cols,5), title='Normalizer Patch') df2.figure(plotnum=(num_rows, num_cols,6), title='Normalizer Warped') df2.set_figtitle('Top '+str(low)+' to '+str(high)+' scoring matches') if not draw_chips: return # # Draw on full images cx2_rchip[qcx] = hs.get_chip(qcx) cx_keys = cx2_kplist.keys() cx_vals = map(len, cx2_kplist.values()) cx_list = [x for (y,x) in sorted(zip(cx_vals, cx_keys))][::-1] num_chips = len(cx_list) pltnum_fn = lambda ix: (int(np.ceil(num_chips/2)), 2, ix) plotnum = pltnum_fn(1) fig2 = df2.figure(fignum-1, plotnum=plotnum) for ix, cx in enumerate(cx_list): plotnum = pltnum_fn(ix+1) fig2 = df2.figure(fignum-1, plotnum=plotnum) rchip = cx2_rchip[cx] fig, ax = df2.imshow(rchip) title_pref = '' color = df2.BLUE if res.qcx == cx: title_pref = 'q' color = df2.GREEN df2.draw_kpts2(cx2_kplist[cx], ell_color=color, ell_alpha=1) df2.draw_border(ax, color, 2) nx = cx2_nx[cx] ax.set_title(title_pref+'cx = %r; nx=%r' % (cx, nx)) gname = hs.get_gname(cx) ax.set_xlabel(gname)
rchip_fpath = 'tpl/extern_feat/zebra.jpg' rchip_fpath = os.path.realpath(rchip_fpath) rchip = cv2.cvtColor(cv2.imread(rchip_fpath, flags=cv2.IMREAD_COLOR), cv2.COLOR_BGR2RGB) outname = extern_feat.compute_perdoch_text_feats(rchip_fpath) #outname = compute_inria_text_feats(rchip_fpath, 'harris', 'sift') # Keep the wrong way to compare kpts0, desc = extern_feat.read_text_feat_file(outname) invE = extern_feat.expand_invET(kpts0[:,2:5].T)[0] kpts1 = extern_feat.fix_kpts_hack(kpts0[:], method=1) A1 = extern_feat.expand_acd(kpts1[:,2:5])[0] #kpts, desc = filter_kpts_scale(kpts, desc) df2.figure(1, doclf=True) df2.DARKEN = .5 #---- df2.imshow(rchip, plotnum=(2,3,1), title='0 before (inverse square root)') draw_kpts3(kpts0.copy(),0) #---- df2.imshow(rchip, plotnum=(2,3,2), title='1 just inverse') draw_kpts3(kpts1.copy(),1) #---- df2.imshow(rchip, plotnum=(2,3,3), title='2 identity') draw_kpts3(kpts1.copy(), 2) df2.update() #---- df2.imshow(rchip, plotnum=(2,3,4), title='3 identity') draw_kpts3(kpts1.copy(), 3) df2.update()
def draw_one_kp(patch, kp, plotx, color, desc=None): fig, ax = df2.imshow(patch, plotnum=(num_rows, num_cols, plotx)) df2.draw_kpts2([kp], ell_color=color, pts=True) if not desc is None and not '--nodesc' in sys.argv: df2.draw_sift(desc, [kp]) df2.draw_border(ax, color, 1)
def get_kp_border(rchip, kp): np.set_printoptions(precision=8) df2.reset() df2.figure(9003, docla=True, doclf=True) def _plotpts(data, px, color=df2.BLUE, label=''): #df2.figure(9003, docla=True, pnum=(1, 1, px)) df2.plot2(data.T[0], data.T[1], '-', '', color=color, label=label) df2.update() def _plotarrow(x, y, dx, dy, color=df2.BLUE, label=''): ax = df2.gca() arrowargs = dict(head_width=.5, length_includes_head=True, label='') arrow = df2.FancyArrow(x, y, dx, dy, **arrowargs) arrow.set_edgecolor(color) arrow.set_facecolor(color) ax.add_patch(arrow) df2.update() def _2x2_eig(M2x2): (evals, evecs) = np.linalg.eig(M2x2) l1, l2 = evals v1, v2 = evecs return l1, l2, v1, v2 #----------------------- # INPUT #----------------------- # We are given the keypoint in invA format (x, y, ia11, ia21, ia22), ia12 = kp, 0 # invA2x2 is a transformation from points on a unit circle to the ellipse invA2x2 = np.array([[ia11, ia12], [ia21, ia22]]) #----------------------- # DRAWING #----------------------- # Lets start off by drawing the ellipse that we are goign to work with # Create unit circle sample tau = 2 * np.pi theta_list = np.linspace(0, tau, 1000) cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list]) ellipse_pts = invA2x2.dot(cicrle_pts.T).T _plotpts(ellipse_pts, 0, df2.BLACK, label='invA2x2.dot(unit_circle)') l1, l2, v1, v2 = _2x2_eig(invA2x2) dx1, dy1 = (v1 * l1) dx2, dy2 = (v2 * l2) _plotarrow(0, 0, dx1, dy1, color=df2.ORANGE, label='invA2x2 e1') _plotarrow(0, 0, dx2, dy2, color=df2.RED, label='invA2x2 e2') #----------------------- # REPRESENTATION #----------------------- # A2x2 is a transformation from points on the ellipse to a unit circle A2x2 = np.linalg.inv(invA2x2) # Points on a matrix satisfy (x).T.dot(E2x2).dot(x) = 1 E2x2 = A2x2.T.dot(A2x2) #Lets check our assertion: (x).T.dot(E2x2).dot(x) = 1 checks = [pt.T.dot(E2x2).dot(pt) for pt in ellipse_pts] assert all([abs(1 - check) < 1E-11 for check in checks]) #----------------------- # CONIC SECTIONS #----------------------- # All of this was from the Perdoch paper, now lets move into conic sections # We will use the notation from wikipedia # http://en.wikipedia.org/wiki/Conic_section # http://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections # The matrix representation of a conic is: ((A, B, B_, C), (D, E, F)) = (E2x2.flatten(), (0, 0, 1)) assert B == B_, 'matrix should by symmetric' # A_Q is our conic section (aka ellipse matrix) A_Q = np.array(((A, B / 2, D / 2), (B / 2, C, E / 2), (D / 2, E / 2, F))) assert np.linalg.det(A_Q) != 0, 'degenerate conic' # As long as det(A_Q) is not 0 it is not degenerate and we can work with the # minor 2x2 matrix A_33 = np.array(((A, B / 2), (B / 2, C))) # (det == 0)->parabola, (det < 0)->hyperbola, (det > 0)->ellipse assert np.linalg.det(A_33) > 0, 'conic is not an ellipse' # Centers are obtained by solving for where the gradient of the quadratic # becomes 0. Without going through the derivation the calculation is... # These should be 0, 0 if we are at the origin, or our original x, y # coordinate specified by the keypoints. I'm doing the calculation just for # shits and giggles x_center = (B * E - (2 * C * D)) / (4 * A * C - B**2) y_center = (D * B - (2 * A * E)) / (4 * A * C - B**2) #================= # DRAWING #================= # Now we are going to determine the major and minor axis # of this beast. It just the center augmented by the eigenvecs l1, l2, v1, v2 = _2x2_eig(A_33) dx1, dy1 = 0 - (v1 / np.sqrt(l1)) dx2, dy2 = 0 - (v2 / np.sqrt(l2)) _plotarrow(0, 0, dx1, dy1, color=df2.BLUE) _plotarrow(0, 0, dx2, dy2, color=df2.BLUE) # The angle between the major axis and our x axis is: x_axis = np.array([1, 0]) theta = np.arccos(x_axis.dot(evec1)) # The eccentricity is determined by: nu = 1 numer = 2 * np.sqrt((A - C)**2 + B**2) denom = nu * (A + C) + np.sqrt((A - C)**2 + B**2) eccentricity = np.sqrt(numer / denom) from scipy.special import ellipeinc # Algebraic form of connic #assert (a * (x ** 2)) + (b * (x * y)) + (c * (y ** 2)) + (d * x) + (e * y) + (f) == 0 #--------------------- invA = np.array([[a, 0], [c, d]]) Ashape = np.linalg.inv(np.array([[a, 0], [c, d]])) Ashape /= np.sqrt(np.linalg.det(Ashape)) tau = 2 * np.pi nSamples = 100 theta_list = np.linspace(0, tau, nSamples) # Create unit circle sample cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list]) circle_hpts = np.hstack([cicrle_pts, np.ones((len(cicrle_pts), 1))]) # Transform as if the unit cirle was the warped patch ashape_pts = Ashape.dot(cicrle_pts.T).T inv = np.linalg.inv svd = np.linalg.svd U, S_, V = svd(Ashape) S = np.diag(S_) pxl_list3 = invA.dot(cicrle_pts[:, 0:2].T).T pxl_list4 = invA.dot(ashape_pts[:, 0:2].T).T pxl_list5 = invA.T.dot(cicrle_pts[:, 0:2].T).T pxl_list6 = invA.T.dot(ashape_pts[:, 0:2].T).T pxl_list7 = inv(V).dot(ashape_pts[:, 0:2].T).T pxl_list8 = inv(U).dot(ashape_pts[:, 0:2].T).T df2.draw() def _plot(data, px, title=''): df2.figure(9003, docla=True, pnum=(2, 4, px)) df2.plot2(data.T[0], data.T[1], '.', title) df2.figure(9003, doclf=True) _plot(cicrle_pts, 1, 'unit circle') _plot(ashape_pts, 2, 'A => circle shape') _plot(pxl_list3, 3) _plot(pxl_list4, 4) _plot(pxl_list5, 5) _plot(pxl_list6, 6) _plot(pxl_list7, 7) _plot(pxl_list8, 8) df2.draw() invA = np.array([[a, 0, x], [c, d, y], [0, 0, 1]]) pxl_list = invA.dot(circle_hpts.T).T[:, 0:2] df2.figure(9002, doclf=True) df2.imshow(rchip) df2.plot2(pxl_list.T[0], pxl_list.T[1], '.') df2.draw() vals = [cv2.getRectSubPix(rchip, (1, 1), tuple(pxl)) for pxl in pxl_list] return vals
def get_kp_border(rchip, kp): np.set_printoptions(precision=8) df2.reset() df2.figure(9003, docla=True, doclf=True) def _plotpts(data, px, color=df2.BLUE, label=''): #df2.figure(9003, docla=True, pnum=(1, 1, px)) df2.plot2(data.T[0], data.T[1], '-', '', color=color, label=label) df2.update() def _plotarrow(x, y, dx, dy, color=df2.BLUE, label=''): ax = df2.gca() arrowargs = dict(head_width=.5, length_includes_head=True, label='') arrow = df2.FancyArrow(x, y, dx, dy, **arrowargs) arrow.set_edgecolor(color) arrow.set_facecolor(color) ax.add_patch(arrow) df2.update() def _2x2_eig(M2x2): (evals, evecs) = np.linalg.eig(M2x2) l1, l2 = evals v1, v2 = evecs return l1, l2, v1, v2 #----------------------- # INPUT #----------------------- # We are given the keypoint in invA format (x, y, ia11, ia21, ia22), ia12 = kp, 0 # invA2x2 is a transformation from points on a unit circle to the ellipse invA2x2 = np.array([[ia11, ia12], [ia21, ia22]]) #----------------------- # DRAWING #----------------------- # Lets start off by drawing the ellipse that we are goign to work with # Create unit circle sample tau = 2 * np.pi theta_list = np.linspace(0, tau, 1000) cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list]) ellipse_pts = invA2x2.dot(cicrle_pts.T).T _plotpts(ellipse_pts, 0, df2.BLACK, label='invA2x2.dot(unit_circle)') l1, l2, v1, v2 = _2x2_eig(invA2x2) dx1, dy1 = (v1 * l1) dx2, dy2 = (v2 * l2) _plotarrow(0, 0, dx1, dy1, color=df2.ORANGE, label='invA2x2 e1') _plotarrow(0, 0, dx2, dy2, color=df2.RED, label='invA2x2 e2') #----------------------- # REPRESENTATION #----------------------- # A2x2 is a transformation from points on the ellipse to a unit circle A2x2 = np.linalg.inv(invA2x2) # Points on a matrix satisfy (x).T.dot(E2x2).dot(x) = 1 E2x2 = A2x2.T.dot(A2x2) #Lets check our assertion: (x).T.dot(E2x2).dot(x) = 1 checks = [pt.T.dot(E2x2).dot(pt) for pt in ellipse_pts] assert all([abs(1 - check) < 1E-11 for check in checks]) #----------------------- # CONIC SECTIONS #----------------------- # All of this was from the Perdoch paper, now lets move into conic sections # We will use the notation from wikipedia # http://en.wikipedia.org/wiki/Conic_section # http://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections # The matrix representation of a conic is: ((A, B, B_, C), (D, E, F)) = (E2x2.flatten(), (0, 0, 1)) assert B == B_, 'matrix should by symmetric' # A_Q is our conic section (aka ellipse matrix) A_Q = np.array((( A, B / 2, D / 2), (B / 2, C, E / 2), (D / 2, E / 2, F))) assert np.linalg.det(A_Q) != 0, 'degenerate conic' # As long as det(A_Q) is not 0 it is not degenerate and we can work with the # minor 2x2 matrix A_33 = np.array((( A, B / 2), (B / 2, C))) # (det == 0)->parabola, (det < 0)->hyperbola, (det > 0)->ellipse assert np.linalg.det(A_33) > 0, 'conic is not an ellipse' # Centers are obtained by solving for where the gradient of the quadratic # becomes 0. Without going through the derivation the calculation is... # These should be 0, 0 if we are at the origin, or our original x, y # coordinate specified by the keypoints. I'm doing the calculation just for # shits and giggles x_center = (B * E - (2 * C * D)) / (4 * A * C - B ** 2) y_center = (D * B - (2 * A * E)) / (4 * A * C - B ** 2) #================= # DRAWING #================= # Now we are going to determine the major and minor axis # of this beast. It just the center augmented by the eigenvecs l1, l2, v1, v2 = _2x2_eig(A_33) dx1, dy1 = 0 - (v1 / np.sqrt(l1)) dx2, dy2 = 0 - (v2 / np.sqrt(l2)) _plotarrow(0, 0, dx1, dy1, color=df2.BLUE) _plotarrow(0, 0, dx2, dy2, color=df2.BLUE) # The angle between the major axis and our x axis is: x_axis = np.array([1, 0]) theta = np.arccos(x_axis.dot(evec1)) # The eccentricity is determined by: nu = 1 numer = 2 * np.sqrt((A - C) ** 2 + B ** 2) denom = nu * (A + C) + np.sqrt((A - C) ** 2 + B ** 2) eccentricity = np.sqrt(numer / denom) from scipy.special import ellipeinc # Algebraic form of connic #assert (a * (x ** 2)) + (b * (x * y)) + (c * (y ** 2)) + (d * x) + (e * y) + (f) == 0 #--------------------- invA = np.array([[a, 0], [c, d]]) Ashape = np.linalg.inv(np.array([[a, 0], [c, d]])) Ashape /= np.sqrt(np.linalg.det(Ashape)) tau = 2 * np.pi nSamples = 100 theta_list = np.linspace(0, tau, nSamples) # Create unit circle sample cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list]) circle_hpts = np.hstack([cicrle_pts, np.ones((len(cicrle_pts), 1))]) # Transform as if the unit cirle was the warped patch ashape_pts = Ashape.dot(cicrle_pts.T).T inv = np.linalg.inv svd = np.linalg.svd U, S_, V = svd(Ashape) S = np.diag(S_) pxl_list3 = invA.dot(cicrle_pts[:, 0:2].T).T pxl_list4 = invA.dot(ashape_pts[:, 0:2].T).T pxl_list5 = invA.T.dot(cicrle_pts[:, 0:2].T).T pxl_list6 = invA.T.dot(ashape_pts[:, 0:2].T).T pxl_list7 = inv(V).dot(ashape_pts[:, 0:2].T).T pxl_list8 = inv(U).dot(ashape_pts[:, 0:2].T).T df2.draw() def _plot(data, px, title=''): df2.figure(9003, docla=True, pnum=(2, 4, px)) df2.plot2(data.T[0], data.T[1], '.', title) df2.figure(9003, doclf=True) _plot(cicrle_pts, 1, 'unit circle') _plot(ashape_pts, 2, 'A => circle shape') _plot(pxl_list3, 3) _plot(pxl_list4, 4) _plot(pxl_list5, 5) _plot(pxl_list6, 6) _plot(pxl_list7, 7) _plot(pxl_list8, 8) df2.draw() invA = np.array([[a, 0, x], [c, d, y], [0, 0, 1]]) pxl_list = invA.dot(circle_hpts.T).T[:, 0:2] df2.figure(9002, doclf=True) df2.imshow(rchip) df2.plot2(pxl_list.T[0], pxl_list.T[1], '.') df2.draw() vals = [cv2.getRectSubPix(rchip, (1, 1), tuple(pxl)) for pxl in pxl_list] return vals