plt.scatter(x=xL, y=yL, c='r', s=5) plt.show() # middle anmsM = plt.imshow(imgM) plt.scatter(x=xM, y=yM, c='r', s=5) plt.show() # right anmsR = plt.imshow(imgR) plt.scatter(x=xR, y=yR, c='r', s=5) plt.show() print("anms complete") #%% Feature Descriptors descsLR = feat_desc(imgL[:, :, 0], xL, yL) descsLG = feat_desc(imgL[:, :, 1], xL, yL) descsLB = feat_desc(imgL[:, :, 2], xL, yL) descsL = np.concatenate((descsLR, descsLG, descsLB), axis=0) descsMR = feat_desc(imgM[:, :, 0], xM, yM) descsMG = feat_desc(imgM[:, :, 1], xM, yM) descsMB = feat_desc(imgM[:, :, 2], xM, yM) descsM = np.concatenate((descsMR, descsMG, descsMB), axis=0) descsRR = feat_desc(imgR[:, :, 0], xR, yR) descsRG = feat_desc(imgR[:, :, 1], xR, yR) descsRB = feat_desc(imgR[:, :, 2], xR, yR) descsR = np.concatenate((descsRR, descsRG, descsRB), axis=0) print("decriptors complete") #%% Feature Matching
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
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) # ppx, fd = computeSift(square) # ppsx, fdS = computeSift(squareShift) # x = ppx[:,0] # y = ppx[:,1] # xS = ppsx[:,0] # yS = ppsx[:,1] mathingSet1 = feat_match(fdS, fd) mathingSet2 = feat_match(fd, fdS)
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
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)