I am attempting to paint a logo over the top of a landscape image in OpenCV python. I have found answers that can 'blend'/watermark images but I don't want to make the logo transparent, I simply want to display the logo on top of the landscape image and keep the logo opacity (or lack thereof).
I have tried both cv2.add()
and cv2.bitwise_and()
but these are not copying the logo across.
src = cv2.imread('../images/pan1.jpg')
logo = cv2.imread('../images/logo.png') # the background is black which is good because I dont want the black parts
# Ensure the logo image is the same size as the landscape image
logo_resized = np.zeros(src.shape, dtype="uint8")
# Place the logo at the bottom right
logo_resized[ src.shape[0] - logo.shape[0] : src.shape[0], src.shape[1] - logo.shape[1] : src.shape[1]] = logo
# Convert the logo to single channel
logo_gray = cv2.cvtColor(logo_resized, cv2.COLOR_BGR2GRAY)
# Create a mask of the logo image
ret, mask = cv2.threshold(logo_gray, 1, 255, cv2.THRESH_BINARY)
# Combine the landscape and the logo images but use a mask so the black parts of logo don't get copied across
# combined = cv2.bitwise_and(logo_resized, logo_resized, mask=mask)
combined = cv2.add(src, logo_resized, mask=mask)
My result:
The process of combining the masks is very straight forward. Load up either one of the masks as a selection, by holding CMD (CTRL) and left clicking on the mask. With the loaded selection, right click on the second mask, and the menu shown in the image appears.
Hold Alt on your keyboard and click the Layer Mask thumbnail. This will open the Layer Mask. Press Cmd+V (Mac) / Ctrl+V (Windows) to paste the image onto the canvas, then scale and position it accordingly. Following that, click the Layer thumbnail to close the Layer Mask and check out the results.
I presume the following is what you had in mind.
Code:
room = cv2.imread('room.JPG' )
logo = cv2.imread('logo.JPG' )
#--- Resizing the logo to the shape of room image ---
logo = cv2.resize(logo, (room.shape[1], room.shape[0]))
#--- Apply Otsu threshold to blue channel of the logo image ---
ret, logo_mask = cv2.threshold(logo[:,:,0], 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
cv2.imshow('logo_mask', logo_mask)
room2 = room.copy()
#--- Copy pixel values of logo image to room image wherever the mask is white ---
room2[np.where(logo_mask == 255)] = logo[np.where(logo_mask == 255)]
cv2.imshow('room_result.JPG', room2)
cv2.waitKey()
cv2.destroyAllWindows()
Result:
Final result:
The following is the mask obtained from applying Otsu threshold on the blue channel of the logo:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With