print("preprocessing complete") #%% Feature Detection cimgL = corner_detector(grayL) cimgM = corner_detector(grayM) cimgR = corner_detector(grayR) print("corner detector complete") #%% ANMS # call functions max_pts = 300 xL, yL, rmaxL = anms(cimgL, max_pts) xM, yM, rmaxM = anms(cimgM, max_pts) xR, yR, rmaxR = anms(cimgR, max_pts) # ignore features near edge xL, yL = ignore_edge_pts(xL, yL, height, width, 20) xM, yM = ignore_edge_pts(xM, yM, height, width, 20) xR, yR = ignore_edge_pts(xR, yR, height, width, 20) # plot results # left anmsL = plt.imshow(imgL) plt.scatter(x=xL, y=yL, c='r', s=5) plt.show() # middle anmsM = plt.imshow(imgM)
def get_homography(img1, img2, createPlots=True, imgNum=0): imgName = "img" + str(imgNum) max_anms = 2000 gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) c = corner_detector(gray) if createPlots: imgCopy = img1.copy() cCopy = c.copy() cCopy = cv2.dilate(cCopy, None) imgCopy[c > 0] = [0, 0, 255] plt.imshow(cv2.cvtColor(imgCopy, cv2.COLOR_BGR2RGB)) fig = plt.gcf() fig.savefig(imgName + 'corner.png', dpi=200) plt.show() X1, Y1, rmax = anms(c, max_anms) d1 = feat_desc(gray, X1, Y1) kp1 = [] for (_x, _y) in zip(X1, Y1): kp1.append(cv2.KeyPoint(_x, _y, 40)) gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) c = corner_detector(gray) X2, Y2, rmax = anms(c, max_anms) d2 = feat_desc(gray, X2, Y2) kp2 = [] for (_x, _y) in zip(X2, Y2): kp2.append(cv2.KeyPoint(_x, _y, 40)) m, dMatch = feat_match(d1, d2) x1 = [] y1 = [] x2 = [] y2 = [] for k, idx in enumerate(m): if (idx != -1): x1.append(X1[k]) y1.append(Y1[k]) x2.append(X2[idx]) y2.append(Y2[idx]) x1 = np.array(x1) x2 = np.array(x2) y1 = np.array(y1) y2 = np.array(y2) print(x1.shape) H, inlier_ind = ransac_est_homography(x1, y1, x2, y2, 2) if createPlots: mask = np.array(inlier_ind, dtype=bool) mfilter = [] for idx, i in enumerate(mask): if i == True: mfilter.append(dMatch[idx]) img_matches = np.empty((max( img1.shape[0], img2.shape[0]), img1.shape[1] + img2.shape[1], 3), dtype=np.uint8) print(len(mfilter)) f = cv2.drawMatches(img1, kp1, img2, kp2, mfilter, img_matches, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) plt.imshow(cv2.cvtColor(img_matches, cv2.COLOR_BGR2RGB)) fig = plt.gcf() fig.savefig(imgName + 'inliners.png', dpi=200) plt.show() f = cv2.drawMatches(img1, kp1, img2, kp2, dMatch, img_matches, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) plt.imshow(cv2.cvtColor(img_matches, cv2.COLOR_BGR2RGB)) fig = plt.gcf() fig.savefig(imgName + 'outliers.png', dpi=200) plt.show() plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)) fig = plt.gcf() ax1 = fig.add_subplot(111) ax1.scatter(X1, Y1, c='r', s=1, label='ANMS') ax1.scatter(x1[mask], y1[mask], c='b', s=1, label='RANSAC') fig.savefig(imgName + 'ransac.png', dpi=200) plt.show() return H
def mymosaic(img_input): im1 = img_input[0] for i in np.arange(1, img_input.shape[0], 1): im2 = img_input[i] im1_c = corner_detector(im1) im2_c = corner_detector(im2) im1_c[im1_c < 0.29] = 0 im2_c[im2_c < 0.2] = 0 #Adaptive Non Maximum suppresion x_im1, y_im1, r_max_im1 = anms(im1_c, max_pts=500) x_im2, y_im2, r_max_im2 = anms(im2_c, max_pts=500) ####################################################################### ############### PLOTTING FEATURE POINTS AFTER ANMS ################## fig, (ax1, ax2) = plt.subplots(1, 2) ax1.imshow(im1, interpolation='nearest', cmap=plt.cm.gray) ax1.plot(y_im1, x_im1, '.b', markersize=10) ax2.imshow(im2, interpolation='nearest', cmap=plt.cm.gray) ax2.plot(y_im2, x_im2, '.b', markersize=5) plt.show() ####################################################################### #Feature_Descriptor im1_gray = 0.2989 * (im1[:, :, 0]) + 0.5870 * ( im1[:, :, 1]) + 0.1140 * (im1[:, :, 2]) im1_gray = im1_gray.astype(np.uint8) im1_desc = feat_desc(im1_gray, x_im1, y_im1) im2_gray = 0.2989 * (im2[:, :, 0]) + 0.5870 * ( im2[:, :, 1]) + 0.1140 * (im2[:, :, 2]) im2_gray = im2_gray.astype(np.uint8) im2_desc = feat_desc(im2_gray, x_im2, y_im2) #Feature Matching match = feat_match(im1_desc, im2_desc) #Ransac lpos = np.arange(match.shape[0]).reshape(match.shape[0], 1) lpos = lpos[match != -1] x_1, y_1 = x_im1[lpos], y_im1[lpos] x_2, y_2 = x_im2[match[match != -1]], y_im2[match[match != -1]] Homo_lm, inlier_idx = ransac_est_homography(x_1, y_1, x_2, y_2, 0.5) inlier_idx = inlier_idx.astype(np.int32) x_1_post = x_1 * inlier_idx x1_final = x_1_post[x_1_post > 0] x1_final = x1_final.reshape(-1, 1) y_1_post = y_1 * inlier_idx y1_final = y_1_post[y_1_post > 0] y1_final = y1_final.reshape(-1, 1) x_2_post = x_2 * inlier_idx x2_final = x_2_post[x_2_post > 0] x2_final = x2_final.reshape(-1, 1) y_2_post = y_2 * inlier_idx y2_final = y_2_post[y_2_post > 0] y2_final = y2_final.reshape(-1, 1) ###################################################################### ############## PLOTTING MATCHED FEATURES AFTER RANSAC ################# l = x_1.shape[0] set1 = np.zeros((l, 2)) set2 = np.zeros((l, 2)) set1[:, 0] = np.reshape(x_1, (x_1.shape[0], )) set1[:, 1] = np.reshape(y_1, (y_1.shape[0], )) set2[:, 0] = np.reshape(x_2, (x_2.shape[0], )) set2[:, 1] = np.reshape(y_2, (y_2.shape[0], )) set1 = np.array(set1, dtype='int') set2 = np.array(set2, dtype='int') locs = np.where(inlier_idx == 1) locs = locs[0] kp1 = set1[locs, :] kp1 = kp1.astype('int64') kp2 = set2[locs, :] kp2 = kp2.astype('int64') mmtche = np.zeros((kp1.shape[0], 2)) mmtche[:, 0] = np.arange(kp1.shape[0]) mmtche[:, 1] = np.arange(kp1.shape[0]) mmtche = mmtche.astype('int64') fig, ax = plt.subplots(1, 1) plt.gray() plot_matches(ax, im1, im2, kp1, kp2, mmtche) plt.show() ##################################################################### blending_factor = 0.8 x = np.array([0, im1.shape[0] - 1, 0, im1.shape[0] - 1]) y = np.array([0, im1.shape[1] - 1, im1.shape[1] - 1, 0]) x = np.array(x, dtype=int) y = np.array(y, dtype=int) def homography(H, x, y): out = np.vstack((x, y, np.ones((y.shape)))) out = np.matmul(H, out) out[0] = out[0] / out[2] out[1] = out[1] / out[2] return out[0], out[1] x_lim, y_lim = homography(Homo_lm, x, y) min_x, max_x, min_y, max_y = round(np.min(x_lim)), round( np.max(x_lim)), round(np.min(y_lim)), round(np.max(y_lim)) x_trans = np.arange(min_x, max_x) y_trans = np.arange(min_y, max_y) x_trans, y_trans = np.meshgrid(x_trans, y_trans) x_trans = np.transpose( np.reshape(x_trans, (x_trans.shape[0] * x_trans.shape[1], 1))) y_trans = np.transpose( np.reshape(y_trans, (y_trans.shape[0] * y_trans.shape[1], 1))) x_source, y_source = homography(np.linalg.inv(Homo_lm), x_trans, y_trans) x_trans = np.transpose(x_trans) y_trans = np.transpose(y_trans) y_trans.shape x_lower, y_lower, x_high, y_high = int(min(min_x, 0)), int( min(min_y, 0)), int(max(max_x, im1.shape[0])), int(max(max_y, im1.shape[1])) img_canvas = np.zeros((x_high - x_lower + 1, y_high - y_lower + 1, 3)) img_canvas = np.array(img_canvas, dtype='uint8') stitch_x, stitch_y = int(max(1, 1 - x_lower)), int(max(1, 1 - y_lower)) img_canvas[stitch_x:stitch_x + im2.shape[0], stitch_y:stitch_y + im2.shape[1], :] = im2 id1 = np.logical_and(x_source >= 0, x_source < im1.shape[0] - 1) id2 = np.logical_and(y_source >= 0, y_source < im1.shape[1] - 1) id = np.logical_and(id1, id2) x_source = x_source[id] y_source = y_source[id] x_trans = x_trans[id] y_trans = y_trans[id] for i in range(x_trans.shape[0] - 1): ceilPixelx = int(np.ceil(x_source[i])) ceilPixely = int(np.ceil(y_source[i])) floorPixelx = int(np.floor(x_source[i])) floorPixely = int(np.floor(y_source[i])) y_1 = 0.5 * (im1[floorPixelx, ceilPixely, :]) + 0.5 * ( im1[floorPixelx, floorPixely, :]) y_2 = 0.5 * (im1[ceilPixelx, ceilPixely, :]) + 0.5 * ( im1[ceilPixelx, floorPixely, :]) x_avg = (0.5 * y_1) + (0.5 * y_2) if np.all(img_canvas[int(x_trans[i] - x_lower + 1), int(y_trans[i] - y_lower + 1), :]) == 0: img_canvas[int(x_trans[i] - x_lower + 1), int(y_trans[i] - y_lower + 1), :] = x_avg else: img_canvas[int(x_trans[i] - x_lower + 1), int(y_trans[i] - y_lower + 1), :] = 0.7 * ( img_canvas[int(x_trans[i] - x_lower + 1), int(y_trans[i] - y_lower + 1), :]) + (0.3) * (x_avg) img_canvas = img_canvas.astype(np.uint8) im1 = img_canvas plt.imshow(img_canvas) plt.show() img_mosaic = img_canvas return img_mosaic
# square.astype(int) # squareShift = signal.convolve2d(square, np.array([1,0,0,0,0]).reshape((1,5)), mode="same") # #squareShift[4:8,10:12] = 1 # print(square) # print(squareShift) #computeSift(rgb2gray(im)) cmx = corner_detector(square) cmxS = corner_detector(squareShift) print("anms computation") x, y, rmax = anms(cmx, Edge) xS, yS, rmaxS = anms(cmxS, Edge) print("anms done") newSquare = square.copy() newSquareShift = squareShift.copy() newSquare[y, x] = 255 newSquareShift[yS, xS] = 255 Image.fromarray(newSquare.astype("uint8")).show() Image.fromarray(newSquareShift.astype("uint8")).show() fd = feat_desc(square, x, y) fdS = feat_desc(squareShift, xS, yS)
def getHomo(square, squareShift, siftFlag): x = None y = None xS = None yS = None fd = None fdS = None if not siftFlag: cmx = corner_detector(square) cmxS = corner_detector(squareShift) # Normalizing dst_norm = np.empty(cmx.shape, dtype=np.float32) cv2.normalize(cmx, dst_norm, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) dst_norm_scaled = cv2.convertScaleAbs(dst_norm) plt.imshow(cmx, cmap='jet') plt.show() dst_norm = np.empty(cmxS.shape, dtype=np.float32) cv2.normalize(cmxS, dst_norm, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) dst_norm_scaled = cv2.convertScaleAbs(dst_norm) plt.imshow(cmxS, cmap='jet') plt.show() #plt.plot(x,y,'ro') #plt.show() # corners_window = 'Corners detected' # cv2.namedWindow(corners_window) #cv2.imshow('h', dst_norm_scaled) print("anms computation") x, y, rmax = anms(cmx, Edge) xS, yS, rmaxS = anms(cmxS, Edge) print("anms done") #newSquare[y,x] = 255; #newSquareShift[yS, xS] = 255; #Image.fromarray(newSquare.astype("uint8")).show() #Image.fromarray(newSquareShift.astype("uint8")).show() fd = implOne(square, x, y) fdS = implOne(squareShift, xS, yS) print("Descriptor Size") print(fd.shape) else: ppx, fd = computeSift(square) ppsx, fdS = computeSift(squareShift) x = ppx[:, 0] y = ppx[:, 1] xS = ppsx[:, 0] yS = ppsx[:, 1] implot = plt.imshow(square, cmap='gray') plt.plot(x, y, 'ro', markersize=2) plt.show() implot = plt.imshow(squareShift, cmap='gray') plt.plot(xS, yS, 'ro', markersize=2) plt.show() mathingSet1 = feat_match(fdS, fd) mathingSet2 = feat_match(fd, fdS) map1 = {} smx = [] smy = [] dmx = [] dmy = [] for index in range(mathingSet1.shape[0]): if mathingSet1[index] != -1: map1[(x[mathingSet1[index]], y[mathingSet1[index]])] = (xS[index], yS[index]) mathes1to2 = [] skpoints = [] dkpoints = [] count = 0 for index in range(mathingSet2.shape[0]): if mathingSet2[index] != -1: newPoint = (xS[mathingSet2[index]], yS[mathingSet2[index]]) currentPoint = (x[index], y[index]) if currentPoint in map1 and map1[currentPoint] == newPoint: smx.append(x[index]) smy.append(y[index]) mathes1to2.append(cv2.DMatch(count, count, 1)) count += 1 dmx.append(xS[mathingSet2[index]]) dmy.append(yS[mathingSet2[index]]) skpoints.append(cv2.KeyPoint(x=x[index], y=y[index], _size=0)) dkpoints.append( cv2.KeyPoint(x=xS[mathingSet2[index]], y=yS[mathingSet2[index]], _size=0)) smx = np.array(smx) smy = np.array(smy) dmx = np.array(dmx) dmy = np.array(dmy) draw_params = dict(matchColor=(0, 255, 0), singlePointColor=None, matchesMask=None, flags=2) src_pts = np.zeros((smx.shape[0], 2), dtype="float32") dst_pts = np.zeros((smx.shape[0], 2), dtype="float32") src_pts[:, 0] = smx src_pts[:, 1] = smy dst_pts[:, 0] = dmx dst_pts[:, 1] = dmy img3 = cv2.drawMatches(square, skpoints, squareShift, dkpoints, mathes1to2, None, **draw_params) Image.fromarray(img3.astype("uint8")).show() H, inliners = ransac_est_homography(dmx, dmy, smx, smy, SSD_THRES) indexesO = np.where(np.array(inliners) == 0) print(indexesO) indexesI = np.where(np.array(inliners) == 1) print(indexesI) sptsx = smx[indexesO] sptsy = smy[indexesO] dptsx = dmx[indexesO] dptsy = dmy[indexesO] ransacsqaure = square.copy() ransacsqaureshift = squareShift.copy() #ransacsqaure[sptsy,sptsx,:] = [0,0,255] #ransacsqaureshift[dptsy,dptsx,:] = [0,0,255] #ransacsqaure[smy[indexesI],smx[indexesI],:] = [255,0,0] #ransacsqaureshift[dmy[indexesI],dmx[indexesI],:] = [255,0,0] implot = plt.imshow(ransacsqaure, cmap='gray') plt.plot(sptsx, sptsy, 'o', markersize=5) plt.plot(smx[indexesI], smy[indexesI], 'ro', markersize=5) plt.show() implot = plt.imshow(ransacsqaureshift, cmap='gray') plt.plot(dptsx, dptsy, 'o', markersize=5) plt.plot(dmx[indexesI], dmy[indexesI], 'ro', markersize=5) plt.show() return H
# Import Images imgL = cv2.imread('left.jpg') imgM = cv2.imread('middle.jpg') imgR = cv2.imread('right.jpg') # Grayscale grayL = cv2.cvtColor(imgL, cv2.COLOR_BGR2GRAY) grayM = cv2.cvtColor(imgM, cv2.COLOR_BGR2GRAY) grayR = cv2.cvtColor(imgR, cv2.COLOR_BGR2GRAY) # Feature Detection cimg = corner_detector(grayL) # Adaptive Non-Maximal Suppression max_pts = x,y,rmax = anms(cimg, max_pts) # Feature Descriptors descsL = feat_desc(grayL, xL, yL) descsM = feat_desc(grayM, xM, yM) descsR = feat_desc(grayR, xR, yR) # Feature Matching match = feat_match(descs1, descs2) # RAndom Sampling Consensus (RANSAC) H, inlier_ind = ransac_est_homography(x1, y1, x2, y2, thresh) # Frame Mosaicing img_mosaic = mymosaic(img_input)