Problem showing image in imshow

Asked

Viewed 616 times

1

I have a function that opens an image and sums with a random matrix but the function cv2.addWeighted generates the following error even though the types of the two matrices are equal :

Traceback (most recent call last):
  File "/home/user/Área de Trabalho/Pasta/test.py", line 17, in <module>
    Noise()
  File "/home/user/Área de Trabalho/Pasta/test.py", line 10, in Noise
    gaussian_noise = cv2.addWeighted(img,0.5,gaussian, 0.25, 0)
cv2.error: OpenCV(4.0.0) /io/opencv/modules/core/src/arithm.cpp:687: error: (-5:Bad argument) When the input arrays in add/subtract/multiply/divide functions have different types, the output array type must be explicitly specified in function 'arithm_op'

So I decided to add in the same hand( what worked) but at the time of showing, the result is all dark, which does not match the reality. Follow the code :

# -*- coding: utf-8 -*-
import cv2
import numpy as np
def Noise():

   img = cv2.imread('Imagen.jpg')
  # print(img)
   l,c,x=img.shape
   gaussian = np.int_(np.random.random((l, c, 3))*10)
   #gaussian_noise = cv2.addWeighted(img,0.5,gaussian, 0.25, 0)
   gaussian_noise=gaussian+img
   print(gaussian_noise)
   cv2.imshow("Original",img)
   cv2.imshow("Noise",gaussian_noise)
   cv2.waitKey(0)

Noise()

Does anyone know why the cv2.imshow("Noise",gaussian_noise) everything is appearing dark if the matrix has correct values ?

2 answers

2

You’re generating the random numbers wrong, so the matrix gaussian does not have the same data type as the image. The correct way to generate a color random image would be: gaussian = np.round(np.random.rand(l, c, 3) * 255).astype(np.uint8)

Since the two images do not have the same data types, it is not possible to perform the operation with the cv2.addWeighted()

The black color appears, because Opencv displays the image in BGR, which has 3 channels of values from 0 to 255. And the way you’re adding it up, the values are going up 255, generating errors. If you try to show the image after the sum, in matlplotlib you will see an error message, in which matplotlib normalizes the values of gaussian_noise automatically for values between 0 and 255 and then it is possible to display the image. But this is not the right way to do this...

Code

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt

def mostrar_imagem(img):
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.show()

def Noise():

   img = cv2.imread('Imagen.jpg')
  # print(img)
   l,c,x=img.shape
   gaussian = np.round(np.random.rand(l, c, 3) * 255).astype(np.uint8)
   gaussian_noise = cv2.addWeighted(img,0.5,gaussian, 0.25, 0)
   # gaussian_noise=gaussian+img
   print(gaussian_noise)
   # mostrar_imagem(img)

   mostrar_imagem(gaussian_noise)
   
   #Ou Mostra a nova imagem e a original
   cv2.imshow("Original / Noise", np.hstack([img, gaussian_noise]))
   cv2.waitKey(0)


Noise()
  • Thanks for the answer. I found interesting the way in which it generated the random numbers and especially the one of showing the 2 images with np.hstack.

1


Your image img is the type uint8. The error that is happening is because your image gaussian is not of the same type as her.

To solve this, instead of creating the gaussian of the kind int_, you create specifically of the type uint8:

gaussian = np.uint8(np.random.random((l, c, 3))*10)

Your code will look like this:

# -*- coding: utf-8 -*-
import cv2
import numpy as np
def Noise():

   img = cv2.imread('Imagen.jpg')
   l,c,x=img.shape
   gaussian = np.uint8(np.random.random((l, c, 3))*10)
   gaussian_noise = cv2.addWeighted(img,0.5,gaussian, 0.25, 0)
   print(gaussian_noise)
   cv2.imshow("Original",img)
   cv2.imshow("Noise",gaussian_noise)
   cv2.waitKey(0)

Noise()

The manual form you used to try to solve and achieve the result was not working because the cv2.imshow() expects values between 0 and 255 in each position of its matrix. It happens that when adding the img with gaussian, the values exceeded the maximum of 255.

  • I saw that you multiplied the matrix with random values by 10 in the Gaussian variable. You can multiply it to 255 if you want to generate a higher noise.

  • Ah, and how I discovered that your img is of type uint8? I tested by calling console img and in the last line is written the type dtype=uint8.

  • It worked, thanks for the reply.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.