diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..fb5863c Binary files /dev/null and b/.DS_Store differ diff --git a/Final.jpg b/Final.jpg new file mode 100644 index 0000000..fcde914 Binary files /dev/null and b/Final.jpg differ diff --git a/Final2.jpg b/Final2.jpg new file mode 100644 index 0000000..6558982 Binary files /dev/null and b/Final2.jpg differ diff --git a/README.md b/README.md index 301113d..e6c8ce2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ -# carpetHomograpfy +# Adding carpets to images with homography +### Table of content + +1. [Input data](#input-data) +2. [Getting started](#getting-started) + + +## 1. Input data + +As input data a carpet image and a room image are required: + + + +## 2. Getting started diff --git a/app.py b/app.py new file mode 100644 index 0000000..dcae1a3 --- /dev/null +++ b/app.py @@ -0,0 +1,75 @@ +# 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() diff --git a/data/carpet.jpeg b/data/carpet.jpeg new file mode 100644 index 0000000..730f046 Binary files /dev/null and b/data/carpet.jpeg differ diff --git a/data/room.jpg b/data/room.jpg new file mode 100644 index 0000000..fdc7ae8 Binary files /dev/null and b/data/room.jpg differ diff --git a/data/room2.jpg b/data/room2.jpg new file mode 100644 index 0000000..c63752f Binary files /dev/null and b/data/room2.jpg differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c8ef8d7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +opencv-contrib-python +numpy +fire \ No newline at end of file