python - OpenCV mat::convertTo in python
Asked Answered
D

3

29

Is there any function in the OpenCV python wrapper that does the same thing as Mat's convertTo method in OpenCV 2?

I basically want to call this function in python

out.convertTo( out, CV_32F, 1.0/255, 0 );

where out is a grayscale image.

I have already made use of cv.ConvertScale by keeping my dst argument as type CV_32FC1, but I am trying to keep my python code as cv2 conformant as possible. Any clues?

Deontology answered 23/4, 2013 at 6:13 Comment(0)
S
21

You can simply use Numpy functions for this.

eg :

res = np.float32(out)

scaling, you will have to do separately:

res = res*scaling_factor
Selfeducated answered 23/4, 2013 at 6:22 Comment(4)
Are the Numpy functions as fast as the opencv convertTo?Ibsen
you can't just use it because it doesn't resolve overflows as .convertTo doesForebear
@FedorChervinskii You can use clip(res,0,255) to resolve overflows.Speculum
@Mr.WorshipMe, there is a caveat to using clip(): you have to have an array data type that is big enough to hold the overflows in the first place. For this reason, I prefer to use OpenCV functions like convertScaleAbs when possible.Eisegesis
R
15

If you are not trying to convert the data type, use this:

cv2.convertScaleAbs(image, result, alpha, beta)

where alpha is you scale factor and beta is a shift value. More details in the OpenCV docs.

Routine answered 7/11, 2016 at 11:50 Comment(1)
I like this answer better than mine because it automatically handles under/overflow in a single line of code. In general the OpenCV functions handle under/overflow for you and they are fast (and hence they should be preferred over NumPy functions)Eisegesis
E
3

In the OP,

0 < multiplier < 1,

so you don't have to worry about underflow or overflow. Solutions from Adid Rahman K and knipknap will work just fine. And they should be plenty fast.

If, for any reason, you need a multiplier > 1, then you can have problems with overflow. That is, the value is not big enough to fit in the chosen data type. Most OpenCV functions will handle overflow by truncating to the max value of the data type. NumPy, though, will just "roll over" the value (e.g. for an 8 bit data type -- max value 255 -- OpenCV will force 260 to become 255, but NumPy will force 260 to 4!).

So to process an 8 bit grayscale image and handle under/over flows do this:

img2 = np.int16(img1)     # convert to signed 16 bit integer to allow overflow
img2 = scale_factor*img2  # apply scale factor
img2 = clip(img2, 0, 255) # force all values to be between 0 and 255

# after clip img2 is effectively unsigned 8 bit, but make it explicit:
img2 = np.uint8(img2)
Eisegesis answered 27/4, 2018 at 0:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.