This project allows you to create a panoramic view by selecting a corresponding point. Using this correspondences, warp the src img by backward warping and this allows you to make panoramic img using stitch function.
get_coord.py
functions: get_coord
homography.py
functions:
get_homography(src, dst),
ransac(src_points, dst_points, iteration, threshold)
stitch.py
functions:
warp(image, H, target_w, target_h),
stitch(src_img, dst_img)
main.py
functions: stitch_all()
get_coord(ssrc_img, ddst_img): This function allows you to choose correspondences between two images
Args:
ssrc_img: np.ndarray with shape (src_h,src_w,c)
ddst_img: np.ndarray with shape (dst_h,dst_w,c)
Returns:
src_points: np.ndarray with shape (num_points,2), 2=> xy(or wh) axis
dst_points: np.ndarray with shape (num_points,2), 2=> xy(or wh) axis
(i)th correspondence: src_points[i] <-> dst_points[i]
![image](https://private-user-images.githubusercontent.com/87067659/242684556-38300c9f-4745-4e6f-9197-7d692084613d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0ODA4MTUsIm5iZiI6MTczOTQ4MDUxNSwicGF0aCI6Ii84NzA2NzY1OS8yNDI2ODQ1NTYtMzgzMDBjOWYtNDc0NS00ZTZmLTkxOTctN2Q2OTIwODQ2MTNkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDIxMDE1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWEzNDBmMjkxNTZmYzg0OTJkZjg4ZmM1Zjg2NmJjYmJmYWI0MzI5OTQ4NzFmMmRmMTQ5OWMyZGUwMzEwZjY2YjQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.jQx75UVhKZ0oe2n3rmKknkRQB2FI6H8UFP_DaaAlpDQ)
[Usage guideline]
- Two windows (left for src image and right for dst image) are created
1) Click a point at src image and press enter
2) Click the corresponding point at dst image and press enter
- One point correspondence is registered
3) Repeat multiple times as you want
4) After indicating multiple point correspondences,
press enter twice in a row (started by src image) to exit
get_homography(src_points, dst_points): Input of this function can be generated by get_coord function. The output is homography matrix between src_img and dst_img by your own correspondences
Args:
src_points: np.ndarray with shape (num_points,2), 2=> xy(or wh) axis
dst_points: np.ndarray with shape (num_points,2), 2=> xy(or wh) axis
(i)th correspondence: src_points[i] <-> dst_points[i]
Returns:
H: Homography matrix with shape (3,3)
H[2,2] = 1
Ransac(src_points, dst_points, iteration, threshold) :This function allows you to find the best homography among all possibles. The best homography implies that this H has the biggest number of inliers
Args:
src_points: np.ndarray with shape (num_points,2), 2=> xy(or wh) axis
dst_points: np.ndarray with shape (num_points,2), 2=> xy(or wh) axis
(i)th correspondence: src_points[i] <-> dst_points[i]
iteration : the number of iterations to find best homography
threshold : If the error ( input dst_points and calculated dst_points using homography) is less than threshold, then this point becomes inlier.
Output:
H: Best Homography matrix with shape(3,3) , H[2,2] = 1
warp(image, H, target_w, target_h): Warp src_img (using homography matrix H) to the target plane with a window size=(target_h,target_w)
Args:
src_img: np.ndarray with shape (src_h,src_w,c)
H: np.ndarray with shape (3,3)
target_h: int
target_w: int
Returns:
Warped src image
np.ndarray with shape (target_h,target_w,c)
stitch(src_img, dst_img):
1)Manually indicate corresponding points
2) Find src_img -> dst_img homography matrix
3) Warp src_img and stitch with dst_img
Args:
src_img: np.ndarray with shape (src_h,src_w,c)
dst_img: np.ndarray with shape (dst_h,dst_w,c)
Returns:
src,dst stitched image. np.ndarray with shape (target_h,target_w,c)
Notice:
get_homography() or ransac() function should be used for computing homography
warp() function should be used for warping an image
[Example]
![image](https://private-user-images.githubusercontent.com/87067659/242684708-116c2199-e914-4c8c-8826-bf211767e089.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0ODA4MTUsIm5iZiI6MTczOTQ4MDUxNSwicGF0aCI6Ii84NzA2NzY1OS8yNDI2ODQ3MDgtMTE2YzIxOTktZTkxNC00YzhjLTg4MjYtYmYyMTE3NjdlMDg5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDIxMDE1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTU5YTdhZDI5NzU4M2ZlZTBjNjBjMzI1NzlkMDQ5NGZmOTQwMGU3NWI5MmJkMTdhNzc4YzA0MmRkZjNhNDBjNzEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.SFplZAwcDk488CY9dRU7_G16IGq8pucUuWV1DlR8g7Y)
![image](https://private-user-images.githubusercontent.com/87067659/242684987-ee81cda0-a745-4797-93ed-b8ddea9a6919.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0ODA4MTUsIm5iZiI6MTczOTQ4MDUxNSwicGF0aCI6Ii84NzA2NzY1OS8yNDI2ODQ5ODctZWU4MWNkYTAtYTc0NS00Nzk3LTkzZWQtYjhkZGVhOWE2OTE5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDIxMDE1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE1MjA0YzRjZGViYjhlNTk1YjA0NDA1NjA5MzI0ZjQ2OGUzMDk1NDg2YjIxNWUwNjEwMDM4MGMxMGJjMjQwMTQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.L8cP3FuDrhq0Kh5g6zJ2qrpD0AlgTAxMcu1B7HzgaUs)
#stitched boudary
![image](https://private-user-images.githubusercontent.com/87067659/242685095-dea8da32-7bfa-4144-abbe-6db3211d02a7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0ODA4MTUsIm5iZiI6MTczOTQ4MDUxNSwicGF0aCI6Ii84NzA2NzY1OS8yNDI2ODUwOTUtZGVhOGRhMzItN2JmYS00MTQ0LWFiYmUtNmRiMzIxMWQwMmE3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDIxMDE1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTFhNGM4Nzc5MGM4NTFiYzliOGI5ZGYwNDFiZDY0OTZkYWRjZTc4MDVmY2QyNmRlNDY5NmQwYjM3NDVkZDMwNDYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.e2aYVND1uMBFILUipyTc8pdgEYm9aUX945kTHF1LPE0)
![image](https://private-user-images.githubusercontent.com/87067659/242685294-c85b6e1c-6ee0-4189-9bf3-317499162330.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk0ODA4MTUsIm5iZiI6MTczOTQ4MDUxNSwicGF0aCI6Ii84NzA2NzY1OS8yNDI2ODUyOTQtYzg1YjZlMWMtNmVlMC00MTg5LTliZjMtMzE3NDk5MTYyMzMwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEzVDIxMDE1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTJiN2FjZTkyYzZjZDRkNzY4OTQ1MjAzNTM0N2U5YjYwMWI2MzJiZWZhYjhjZWUzYThkN2IwMmVmNWQyMTVjY2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.bS3kbkTgNQ3YOvofd3RoWdfcWoTzZm990qQkgQixFbA)