jhill515
jhill515

Reputation: 943

OpenCV merge failing to merge image channel

I'm attempting to add Gaussian noise to a single channel of an image.

import cv2 as cv
import numpy as np

img1 = cv.imread('input/foo.png')
img1_blue, img1_green, img1_red = cv.split(img1)
img1_h, img1_w, _ = img1.shape

s = 5
noise = np.random.normal(0, s, (img1_h, img1_w))
img1_gn = img1_green + noise

print(img1_green.shape) # (512, 384)
print(img1_gn.shape)    # (512, 384)
print(img1_blue.shape)  # (512, 384)

img1_g_noise = cv.merge((img1_blue, img1_gn, img1_red))

This results in the following error:

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-34-049cf9e65133> in <module>
     13 
---> 14 img1_g_noise = cv.merge((img1_blue, img1_gn, img1_red))
     15 

error: OpenCV(3.4.5) /io/opencv/modules/core/src/merge.cpp:293: error: (-215:Assertion failed) mv[i].size == mv[0].size && mv[i].depth() == depth in function 'merge'

I'm not sure how or why this is happening. The resulting noisy green channel has the same dimensions and type as the other two channels. Recombining the original green channel works just fine. Any steering direction is appreciated, and thank you in advance.

Upvotes: 2

Views: 3187

Answers (2)

one
one

Reputation: 2585

this is the dtype problem.

by default, the image_blue and image_red are uint8 type; but the noise is float16 type.


Solution1

you can change the noise to 'unint8` type by:

noise = noise.astype('image_red.type')

but this will let the noise loss much information.


Solution2

you can also change the all of the rgb channel to float16 dtype, by adding this two line:

img1_blue = img1_blue.astype(img1_gn.dtype)
img1_red = img1_red.astype(img1_gn.dtype)

Upvotes: 1

Peyman habibi
Peyman habibi

Reputation: 810

This is because noise and channel datatype mismatch. numpy matrix has default datatype of numpy.float64. and you have to define noise in type of rach channel by adding .astype(img1_blue.dtype) to noise defenition.

edited code :

import cv2 as cv
import numpy as np

img1 = cv.imread('list.JPG')
img1_blue, img1_green, img1_red = cv.split(img1)
img1_h, img1_w, _ = img1.shape

s = 5
noise = np.random.normal(0, s, (img1_h, img1_w)).astype(img1_blue.dtype)
img1_gn = img1_green + noise

print(img1_green.shape) # (512, 384)
print(img1_gn.shape)    # (512, 384)
print(img1_blue.shape)  # (512, 384)

img1_g_noise = cv.merge((img1_blue, img1_gn, img1_red))
cv.imshow("img1_g_noise",img1_g_noise)
cv2.waitKey()

Upvotes: 2

Related Questions