Open monkeycc opened 2 years ago
import cv2 import numpy as np import sys class Image_Stitching(): def __init__(self) : self.ratio=0.85 self.min_match=10 self.sift=cv2.SIFT_create() self.smoothing_window_size=800 def registration(self,img1,img2,img3): kp1, des1 = self.sift.detectAndCompute(img1, None) kp2, des2 = self.sift.detectAndCompute(img2, None) kp3, des3 = self.sift.detectAndCompute(img3, None) matcher = cv2.BFMatcher() raw_matches = matcher.knnMatch(des1, des2, des3, k=3) good_points = [] good_matches=[] for m1, m2 in raw_matches: if m1.distance < self.ratio * m2.distance: good_points.append((m1.trainIdx, m1.queryIdx)) good_matches.append([m1]) img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, img3, kp3, good_matches, None, flags=3) cv2.imwrite('matching.jpg', img3) if len(good_points) > self.min_match: image1_kp = np.float32( [kp1[i].pt for (_, i) in good_points]) image2_kp = np.float32( [kp2[i].pt for (i, _) in good_points]) image3_kp = np.float32( [kp3[i].pt for (i, _) in good_points]) H, status = cv2.findHomography(image2_kp, image1_kp,image3_kp, cv2.RANSAC,5.0) return H def create_mask(self,img1,img2,img3,version): height_img1 = img1.shape[0] width_img1 = img1.shape[1] width_img2 = img2.shape[1] width_img3 = img3.shape[1] height_panorama = height_img1 width_panorama = width_img1 +width_img2 +width_img3 offset = int(self.smoothing_window_size / 2) barrier = img1.shape[1] - int(self.smoothing_window_size / 2) mask = np.zeros((height_panorama, width_panorama)) if version== 'left_image': mask[:, barrier - offset:barrier + offset ] = np.tile(np.linspace(1, 0, 2 * offset ).T, (height_panorama, 1)) mask[:, :barrier - offset] = 1 else: mask[:, barrier - offset :barrier + offset ] = np.tile(np.linspace(0, 1, 2 * offset ).T, (height_panorama, 1)) mask[:, barrier + offset:] = 1 return cv2.merge([mask, mask, mask]) def blending(self,img1,img2,img3): H = self.registration(img1,img2,img3) height_img1 = img1.shape[0] width_img1 = img1.shape[1] width_img2 = img2.shape[1] width_img3 = img3.shape[1] height_panorama = height_img1 width_panorama = width_img1 +width_img2 +width_img3 panorama1 = np.zeros((height_panorama, width_panorama, 3)) mask1 = self.create_mask(img1,img2,img3,version='left_image') panorama1[0:img1.shape[0], 0:img1.shape[1], :] = img1 panorama1 *= mask1 mask2 = self.create_mask(img1,img2,img3,version='right_image') panorama2 = cv2.warpPerspective(img2, H, (width_panorama, height_panorama))*mask2 panorama1 *= mask2 mask3 = self.create_mask(img1,img2,img3,version='right_image') panorama3 = cv2.warpPerspective(img3, H, (width_panorama, height_panorama))*mask3 result=panorama1+panorama2+panorama3 rows, cols = np.where(result[:, :, 0] != 0) min_row, max_row = min(rows), max(rows) + 1 min_col, max_col = min(cols), max(cols) + 1 final_result = result[min_row:max_row, min_col:max_col, :] return final_result def main(argv1,argv2,argv3): img1 = cv2.imread(argv1) img2 = cv2.imread(argv2) img3 = cv2.imread(argv3) final=Image_Stitching().blending(img1,img2,img3) cv2.imwrite('panorama.jpg', final) if __name__ == '__main__': try: main(sys.argv[1],sys.argv[2],sys.argv[3]) except IndexError: print ("Please input two source images: ") print ("For example: python Image_Stitching.py '/Users/linrl3/Desktop/picture/p1.jpg' '/Users/linrl3/Desktop/picture/p2.jpg'")
My method is wrong
My method is wrong