Image-Stitching-OpenCV
Image-Stitching-OpenCV copied to clipboard
How to three pictures
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