6

I have two images. I want to grab a region (polygon, not rectangle) from one image and copy that region onto the other image. How can I accomplish this? Here is what I have so far.

import cv2
import numpy as np

#load two images
srcfilename = 'foo.jpg'
src1 = cv2.imread(srcfilename)
srcfilename = 'bar.jpg'
src2 = cv2.imread(srcfilename)


src1_mask = np.zeros(src1.shape[:-1])
#create a polygon for region of interest
poly = np.array([ [150,150], [200,100], [350,150], [350,200], [300,220], [200,200], [190,180] ], np.int32)
cv2.fillPoly(src1_mask, [poly], 255)

at this point I have my two images loaded and I have a polygon and mask for the region. Now I don't know how to use this mask/polygon to copy that part of src1 onto src2.

#I can also create a mask that has the same number of channels (3)
src1_mask = np.zeros(src1.shape)
#create a polygon for region of interest
poly = np.array([ [150,150], [200,100], [350,150], [350,200], [300,220], [200,200], [190,180] ], np.int32)
cv2.fillPoly(src1_mask, [poly], (255,255,255))

FINAL EDIT

Using bitwise operations I have been able to achieve what I wanted. Here is example code.

import cv2
import numpy as np
import matplotlib.pyplot as pst

#load two images
srcfilename = 'foo.jpg'
src1 = cv2.imread(srcfilename)
srcfilename = 'bar.jpg'
src2 = cv2.imread(srcfilename)

#create mask template
src1_mask = src1.copy()
src1_mask = cv2.cvtColor(src1_mask,cv2.COLOR_BGR2GRAY)
src1_mask.fill(0)

#define polygon around region
poly = np.array([ [0,0], [20,0], [65,40], [150,40], [225,5], [225,170],[120,200], [10,190] ], np.int32)

#fill polygon in mask
_ = cv2.fillPoly(src1_mask, [poly], 255)

#create region of interest
roi = src2[np.min(poly[:,1]):np.max(poly[:,1]),np.min(poly[:,0]):np.max(poly[:,0])]
mask = src1_mask[np.min(poly[:,1]):np.max(poly[:,1]),np.min(poly[:,0]):np.max(poly[:,0])]

mask_inv = cv2.bitwise_not(mask)
img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)
src1_cut = src1[np.min(poly[:,1]):np.max(poly[:,1]),np.min(poly[:,0]):np.max(poly[:,0])]

img2_fg = cv2.bitwise_and(src1_cut,src1_cut,mask = mask)

# Put logo in ROI and modify the main image
dst = cv2.add(img1_bg,img2_fg)
src2_final = src2.copy()
src2_final[np.min(poly[:,1]):np.max(poly[:,1]),np.min(poly[:,0]):np.max(poly[:,0])] = dst

plt.imshow(cv2.cvtColor(src2_final, cv2.COLOR_BGR2RGB))
1
  • 1
    Great answer, i searched for this for soooo long and i even tried the answer below, but I'm probably too stupid to use it, TYSFM Commented Jan 24, 2023 at 19:33

2 Answers 2

5

Assuming that src1 is your image and src1_mask is your binary mask:

    src1_mask=cv2.cvtColor(src1_mask,cv2.COLOR_GRAY2BGR)#change mask to a 3 channel image 
    mask_out=cv2.subtract(src1_mask,src1)
    mask_out=cv2.subtract(src1_mask,mask_out)

Now mask_out contains the part of the image src1 located inside the polygon you defined.

Sign up to request clarification or add additional context in comments.

Comments

2

Assuming src1 is source image poly is your polygon, src2 is destination image onto which you want to copy poly.

Copy poly to mask:

mask = np.zeros(src1.shape)
cv2.fillPoly(mask,[poly],1)
poly_copied = np.multiply(mask,src1)

Maskout poly in src2:

mask = np.ones(src2)
#assuming src1 and src2 are of same size
cv2.fillPoly(mask,[poly],0)
src2 = np.multiply(mask,src2)

Copy poly to src2:

src2 = np.add(poly_copied,src2)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.