How do I stitch the two images together?

Viewed 75

I have two images and need to stitch them together to make one whole picture. I need to sew them together using code (c++ or python), without using photoshop. I tried to do it myself with opencv, but it didn't work. These are the two images that need to be stitched stitch:

1 image: enter image description here

2 image: enter image description here

In addition here are two more images that are slightly different than those listed above. These two images also need to be stitch.

1 image: enter image description here

2 image:enter image description here

Best result I could get: enter image description here

My code written in python:

import cv2 as cv
import numpy as np


def FindHomography(Matches, BaseImage_kp, SecImage_kp):
    # If less than 4 matches found, exit the code.
    if len(Matches) < 4:
        print("\nNot enough matches found between the images.\n")
        exit(0)

    # Storing coordinates of points corresponding to the matches found in both the images
    BaseImage_pts = []
    SecImage_pts = []
    for Match in Matches:
        BaseImage_pts.append(BaseImage_kp[Match[0].queryIdx].pt)
        SecImage_pts.append(SecImage_kp[Match[0].trainIdx].pt)

    # Changing the datatype to "float32" for finding homography
    BaseImage_pts = np.float32(BaseImage_pts)
    SecImage_pts = np.float32(SecImage_pts)

    # Finding the
    (HomographyMatrix, Status) = cv.findHomography(SecImage_pts, BaseImage_pts, cv.RANSAC, 4.0)

    return HomographyMatrix, Status


def GetNewFrameSizeAndMatrix(HomographyMatrix, Sec_ImageShape, Base_ImageShape):
    # Reading the size of the image
    (Height, Width) = Sec_ImageShape

    # Taking the matrix of initial coordinates of the corners of the secondary image
    # Stored in the following format: [[x1, x2, x3, x4], [y1, y2, y3, y4], [1, 1, 1, 1]]
    # Where (xi, yi) is the coordinate of the i th corner of the image.
    InitialMatrix = np.array([[0, Width - 1, Width - 1, 0],
                              [0, 0, Height - 1, Height - 1],
                              [1, 1, 1, 1]])

    # Finding the final coordinates of the corners of the image after transformation.
    # NOTE: Here, the coordinates of the corners of the frame may go out of the
    # frame(negative values). We will correct this afterwards by updating the
    # homography matrix accordingly.
    FinalMatrix = np.dot(HomographyMatrix, InitialMatrix)

    [x, y, c] = FinalMatrix
    x = np.divide(x, c)
    y = np.divide(y, c)

    # Finding the dimentions of the stitched image frame and the "Correction" factor
    min_x, max_x = int(round(min(x))), int(round(max(x)))
    min_y, max_y = int(round(min(y))), int(round(max(y)))

    New_Width = max_x
    New_Height = max_y
    Correction = [0, 0]
    if min_x < 0:
        New_Width -= min_x
        Correction[0] = abs(min_x)
    if min_y < 0:
        New_Height -= min_y
        Correction[1] = abs(min_y)

    # Again correcting New_Width and New_Height
    # Helpful when secondary image is overlaped on the left hand side of the Base image.
    if New_Width < Base_ImageShape[1] + Correction[0]:
        New_Width = Base_ImageShape[1] + Correction[0]
    if New_Height < Base_ImageShape[0] + Correction[1]:
        New_Height = Base_ImageShape[0] + Correction[1]

    # Finding the coordinates of the corners of the image if they all were within the frame.
    x = np.add(x, Correction[0])
    y = np.add(y, Correction[1])
    OldInitialPoints = np.float32([[0, 0],
                                   [Width - 1, 0],
                                   [Width - 1, Height - 1],
                                   [0, Height - 1]])
    NewFinalPonts = np.float32(np.array([x, y]).transpose())

    # Updating the homography matrix. Done so that now the secondary image completely
    # lies inside the frame
    HomographyMatrix = cv.getPerspectiveTransform(OldInitialPoints, NewFinalPonts)

    return [New_Height, New_Width], Correction, HomographyMatrix


ratio_thresh = 0.54

image1 = cv.imread(filename='/home/msi-user/Рабочий стол/car/code/stitch/all/camera_11_img.jpg',
                   flags=cv.IMREAD_GRAYSCALE)

image2 = cv.imread(filename='/home/msi-user/Рабочий стол/car/code/stitch/all/camera_12_img.jpg',
                   flags=cv.IMREAD_GRAYSCALE)

# -----------------------------------------KAZE--------------------------------#

AKAZE = cv.KAZE_create()  # KAZE, AKAZE, ORB, BRISK, xfeatures2d.SURF

keypoints1, descriptors1 = AKAZE.detectAndCompute(image1, None)
keypoints2, descriptors2 = AKAZE.detectAndCompute(image2, None)

FLANN_INDEX_KDTREE = 1

index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)

descriptors1 = np.float32(descriptors1)
descriptors2 = np.float32(descriptors2)

FLANN = cv.FlannBasedMatcher(indexParams=index_params,
                             searchParams=search_params)

matches = FLANN.knnMatch(queryDescriptors=descriptors1,
                         trainDescriptors=descriptors2,
                         k=2)

good_matches = []
t = []
for m, n in matches:
    if m.distance < ratio_thresh * n.distance:
        good_matches.append([m])
        t.append(m)

output = cv.drawMatches(img1=image1,
                        keypoints1=keypoints1,
                        img2=image2,
                        keypoints2=keypoints2,
                        matches1to2=t,
                        outImg=None,
                        flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

cv.namedWindow("drawMatches.jpg", cv.WINDOW_NORMAL)
cv.imshow("drawMatches.jpg", output)

# ----------------------------------FindHomography-------------------------------------------#

HomographyMatrix, Status = FindHomography(good_matches, keypoints1, keypoints2)

BaseImage = image1
SecImage = image2

NewFrameSize, Correction, HomographyMatrix = GetNewFrameSizeAndMatrix(HomographyMatrix, SecImage.shape[:2],
                                                                      BaseImage.shape[:2])

StitchedImage = cv.warpPerspective(SecImage, HomographyMatrix, (NewFrameSize[1], NewFrameSize[0]))
StitchedImage[Correction[1]:Correction[1] + BaseImage.shape[0],
Correction[0]:Correction[0] + BaseImage.shape[1]] = BaseImage

cv.namedWindow("stisched2.jpg", cv.WINDOW_NORMAL)
cv.imshow("stisched2.jpg", StitchedImage)

while True:
    if cv.waitKey(1) == 27:
        break

Please help

0 Answers
Related