Overlaying a 1 channel skeleton image onto a 3 channel RGB image

Viewed 567

I am interested in overlaying a black and white skeleton image where skeleton pixels are 255 (white) onto a 3 channel RGB image. I am not biased towards using OpenCV but when I used the add function, I got the error for the shape incompatibility.

What is the way to do this?

import cv2
skl_img = cv2.imread("sample_skeleton_image/579366_2_train2017_skel.png", 0) 
print(skl_img.shape)
plt.imshow(skl_img)

224x400

enter image description here

obj_img = cv2.imread("/content/drive/Shareddrives/Wish 2021/Code/sample_skeleton_image/579366_2_train2017.jpg", cv2.IMREAD_COLOR)
plt.imshow(obj_img)

obj_img shape is 224x400x3

enter image description here

final_img = cv2.add(obj_img,skl_img)
plt.imshow(final_img)

error                                     Traceback (most recent call last)
<ipython-input-27-7de7a4136982> in <module>()
----> 1 final_img = cv2.add(obj_img,skl_img)
      2 plt.imshow(final_img)

error: OpenCV(4.1.2) /io/opencv/modules/core/src/arithm.cpp:663: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'arithm_op'

Essentially, I am interested in a final image that looks like the following: enter image description here

2 Answers

Here are several other ways to apply the mask to the image in Python.

Input:

enter image description here

Mask:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('elephant_trunk.png')

# read mask as grayscale
mask = cv2.imread('elephant_trunk_skeleton.png', cv2.IMREAD_GRAYSCALE)

# Method 1: Numpy masking
result1 = img.copy()
result1[mask!=0] = (255,255,255)

# Method 2: Merge mask to 3 channels
mask2 = cv2.merge([mask,mask,mask])
result2 = cv2.add(img, mask2)

# Method 3: Convert mask to BGR
mask3 = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
result3 = cv2.add(img, mask3)

# save result
cv2.imwrite("elephant_trunk_masked.png", result1)

# show result
cv2.imshow("RESULT1", result1)
cv2.imshow("RESULT2", result2)
cv2.imshow("RESULT3", result3)
cv2.waitKey(0)

Result:

enter image description here

Read the 1 channel skeleton image and stacked them into each other to create a 3 channel skeleton image and used add function in cv2

skl_img = cv2.imread("sample_skeleton_image/579366_2_train2017_skel.png", 0) 

obj_img = cv2.imread("/content/drive/Shareddrives/Wish 2021/Code/sample_skeleton_image/579366_2_train2017.jpg", cv2.IMREAD_COLOR)

c3_skel = np.zeros_like(obj_img)
c3_skel[:,:,0] = skl_img
c3_skel[:,:,1] = skl_img
c3_skel[:,:,2] = skl_img
plt.imshow(c3_skel)

enter image description here

final_img = cv2.add(obj_img, c3_skel)
plt.imshow(final_img)

enter image description here

Related