# Importing the dependencies import cv2 import numpy as np # Defining variables to store coordinates where the second image has to be placed positions = [] positions2 = [] count = 0 # Mouse callback function def draw_circle(event, x, y, flags, param): global positions, count # If event is Left Button Click then store the coordinate in the lists, positions and positions2 if event == cv2.EVENT_LBUTTONUP: cv2.circle(room_draw, (x, y), 2, (255, 0, 0), -1) positions.append([x, y]) if count != 3: positions2.append([x, y]) elif count == 3: positions2.insert(2, [x, y]) count += 1 # Reading the two images and storing it in variables room and dp room = cv2.imread("./data/room2.jpg") room_draw = room.copy() dp = cv2.imread("./data/carpet.jpeg") # Defing a window named 'image' and set the callback to define the destination points cv2.namedWindow("image") cv2.setMouseCallback("image", draw_circle) while True: cv2.imshow("image", room_draw) k = cv2.waitKey(20) & 0xFF if k == 27 or count > 3: break cv2.destroyAllWindows() height, width = room.shape[:2] h1, w1 = dp.shape[:2] pts1 = np.float32([[0, 0], [w1, 0], [0, h1], [w1, h1]]) pts2 = np.float32(positions) # Calculate homography h, mask = cv2.findHomography(pts1, pts2, cv2.RANSAC, 5.0) height, width, channels = room.shape im1Reg = cv2.warpPerspective(dp, h, (width, height)) # Masking and blending mask2 = np.zeros(room.shape, dtype=np.uint8) roi_corners2 = np.int32(positions2) channel_count2 = room.shape[2] ignore_mask_color2 = (255,) * channel_count2 cv2.fillConvexPoly(mask2, roi_corners2, ignore_mask_color2) mask2 = cv2.bitwise_not(mask2) masked_image2 = cv2.bitwise_and(room, mask2) # Using Bitwise or to merge the two images final = cv2.bitwise_or(im1Reg, masked_image2) # Show results and write to file cv2.imshow("Final", final) cv2.imwrite("Final2.jpg", final) cv2.waitKey(0) & 0xFF cv2.destroyAllWindows()