In MATLAB, the following code reads in an image and normalizes the values between [0.0,1.0]
:
img=im2double(imread('image.jpg'))
I would like to perform this in OpenCV Python. Is there an equivalent function to do this?
I have tried the following code, but its asking for source IplImage
. Also, what would be the equivalent to imread
in 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
I would avoid using the old cv
module and use cv2
instead as these use numpy
arrays. numpy
arrays operate very similar to arrays and matrices in MATLAB.
In any case, im2double
in MATLAB normalizes an image such that the minimum intensity is 0 and the maximum intensity is 1. You can achieve that by the following relationship, given a pixel in
from the image img
:
out = (in - min(img)) / (max(img) - min(img))
Therefore, you would need to find the minimum and maximum of the image and apply the above operation to every pixel in the image. In the case of multi-channel images, we would find the global minimum and maximum over all channels and apply the same operation to all channels independently.
The short answer to your question is to use cv2.normalize
like so:
out = cv2.normalize(img.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)
The first input is the source image, which we convert to float
. The second input is the output image, but we'll set that to None
as we want the function call to return that for us. The third and fourth parameters specify the minimum and maximum values you want to appear in the output, which is 0 and 1 respectively, and the last output specifies how you want to normalize the image. What I described falls under the NORM_MINMAX
flag.
Your other question is with regards to reading in an image. To read in an image with cv2
, use cv2.imread
. The input into this function is a string that contains the file you want to load in. Therefore, you'd call the above function like so:
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
However, if you'd like to write something yourself, we can very easily do that using numpy
operations.
As such, write your function like so:
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
You'd then use the code like so:
img = cv2.imread('...') # Read in your image
out = im2double(img) # Convert to normalized floating point
More recent versions of MATLAB now simply divide all of the numbers by the largest value supported by that datatype. For example, for uint8
the largest value is 255 while for uint16
the largest value is 65535.
If you wanted to reimplement this for more recent versions of MATLAB, you can use the numpy.iinfo
function to infer what the smallest and largest values of the datatype are and convert accordingly. Simply access the largest value and divide all elements in your image by this number. Make sure you convert the image to a floating-point representation first:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With