Dans MATLAB, le code suivant lit dans une image et normalise les valeurs entre [0.0,1.0]
:
img=im2double(imread('image.jpg'))
Je voudrais effectuer cela en OpenCV Python. Existe-t-il une fonction équivalente pour ce faire?
J'ai essayé le code suivant, mais il demande la source IplImage
. De plus, quel serait l'équivalent de imread
en Python?
def im2double(im):
mat = cvGetMat(im);
if CV_MAT_DEPTH(mat.type)==CV_64F:
return mat
im64f = array(size(im), 'double')
cvConvertScale(im, im64f, 1.0, 0.0)
return im64f
Je voudrais éviter d'utiliser l'ancien module cv
et utiliser cv2
à la place car ceux-ci utilisent des tableaux numpy
. numpy
les tableaux fonctionnent de manière très similaire aux tableaux et matrices de MATLAB.
Dans tout les cas, im2double
dans MATLAB normalise une image de telle sorte que l'intensité minimale est 0 et l'intensité maximale est 1. Vous pouvez y parvenir par la relation suivante, étant donné un pixel in
de l'image img
:
out = (in - min(img)) / (max(img) - min(img))
Par conséquent, vous devez trouver le minimum et le maximum de l'image et appliquer l'opération ci-dessus à chaque pixel de l'image. Dans le cas d'images multicanaux, nous trouverions le global minimum et maximum sur tous les canaux et appliquerions la même opération à tous les canaux indépendamment.
La réponse courte à votre question est d'utiliser cv2.normalize
comme ceci:
out = cv2.normalize(img.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)
La première entrée est l'image source, que nous convertissons en float
. La deuxième entrée est l'image de sortie, mais nous la définirons sur None
car nous voulons que l'appel de fonction nous la renvoie. Les troisième et quatrième paramètres spécifient les valeurs minimales et maximales que vous souhaitez voir apparaître dans la sortie, qui sont respectivement 0 et 1, et la dernière sortie spécifie comment vous souhaitez normaliser l'image. Ce que j'ai décrit relève du NORM_MINMAX
drapeau.
Votre autre question concerne la lecture d'une image. Pour lire dans une image avec cv2
, utilisation cv2.imread
. L'entrée dans cette fonction est une chaîne qui contient le fichier dans lequel vous souhaitez charger. Par conséquent, vous appelleriez la fonction ci-dessus comme suit:
img = cv2.imread('....') # Read image here
out = cv2.normalize(img.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX) # Convert to normalized floating point
Cependant, si vous souhaitez écrire quelque chose vous-même, nous pouvons très facilement le faire en utilisant les opérations numpy
.
En tant que tel, écrivez votre fonction comme suit:
import cv2
import numpy as np
def im2double(im):
min_val = np.min(im.ravel())
max_val = np.max(im.ravel())
out = (im.astype('float') - min_val) / (max_val - min_val)
return out
Vous utiliseriez alors le code comme ceci:
img = cv2.imread('...') # Read in your image
out = im2double(img) # Convert to normalized floating point
Les versions plus récentes de MATLAB divisent maintenant simplement tous les nombres par la plus grande valeur prise en charge par ce type de données. Par exemple, pour uint8
la plus grande valeur est 255 tandis que pour uint16
la valeur la plus élevée est 65535.
Si vous souhaitez réimplémenter cela pour des versions plus récentes de MATLAB, vous pouvez utiliser le numpy.iinfo
fonction pour déduire les valeurs les plus petites et les plus grandes du type de données et les convertir en conséquence. Accédez simplement à la plus grande valeur et divisez tous les éléments de votre image par ce nombre. Assurez-vous de convertir d'abord l'image en virgule flottante:
import cv2
import numpy as np
def im2double(im):
info = np.iinfo(im.dtype) # Get the data type of the input image
return im.astype(np.float) / info.max # Divide all values by the largest possible value in the datatype