Naveen Raja - 1 year ago 78

Python Question

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`

`imread`

`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

Answer Source

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
```