web-dev-qa-db-fra.com

Fonction im2double équivalente dans OpenCV Python

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
14
Naveen Raja

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

Edit - 29 septembre 2016

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