OpenCV Python中的等效im2double函数

Nav*_*ja 13 python matlab opencv image image-processing

在MATLAB中,以下代码读入图像并规范化以下值之间的值[0.0,1.0]:

img=im2double(imread('image.jpg')) 
Run Code Online (Sandbox Code Playgroud)

我想在OpenCV Python中执行此操作.是否有相同的功能来做到这一点?

我尝试了以下代码,但它要求源代码IplImage.另外,imread在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
Run Code Online (Sandbox Code Playgroud)

ray*_*ica 24

我会避免使用旧cv模块,cv2而是使用这些使用numpy数组. numpy数组操作与MATLAB中的数组和矩阵非常相似.

在任何情况下, im2double在MATLAB中规范化图像,使最小强度为0,最大强度为1.您可以通过以下关系实现,给定in图像中的像素img:

out = (in - min(img)) / (max(img) - min(img))
Run Code Online (Sandbox Code Playgroud)

因此,您需要找到图像的最小值和最大值,并将上述操作应用于图像中的每个像素.在多通道图像的情况下,我们将在所有通道上找到全局最小值和最大值,并且将相同的操作独立地应用于所有通道.

对你的问题的简短回答就是这样使用cv2.normalize:

out = cv2.normalize(img.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)
Run Code Online (Sandbox Code Playgroud)

第一个输入是源图像,我们将其转换为float.第二个输入是输出图像,但我们将其设置None为我们希望函数调用为我们返回.第三个和第四个参数指定要出现在输出,分别为0和1的最小值和最大值,最后输出指定如何要标准化图像.我描述的内容属于NORM_MINMAX旗帜.

你的另一个问题是关于阅读图像.为了与图像中读取cv2,使用cv2.imread.此函数的输入是一个包含要加载的文件的字符串.因此,您可以调用上面的函数:

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
Run Code Online (Sandbox Code Playgroud)

但是,如果你想自己写一些东西,我们可以很容易地使用numpy操作.

因此,像这样写你的函数:

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
Run Code Online (Sandbox Code Playgroud)

然后你就像这样使用代码:

img = cv2.imread('...') # Read in your image
out = im2double(img) # Convert to normalized floating point
Run Code Online (Sandbox Code Playgroud)

编辑 - 2016年9月29日

更新版本的MATLAB现在只需将所有数字除以该数据类型支持的最大值.例如,uint8最大值为255,而uint16最大值为65535.

如果您想为更新版本的MATLAB重新实现此numpy.iinfo功能,可以使用该函数来推断数据类型的最小值和最大值是什么,并相应地进行转换.只需访问最大值,并按此数字划分图像中的所有元素.确保首先将图像转换为浮点表示:

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
Run Code Online (Sandbox Code Playgroud)

  • 你写道,"MATLAB中的im2double标准化图像,使最小强度为0,最大强度为1".然后在下一行显示拉伸方程.但是,我不认为`im2double`会这样做,也不会在文档中这样说.例如,拿这个片段:`img = uint8(randi([45 175],25,25,3)); IMG1 = im2double(IMG);`.在我的机器上,`img1`位于`[0.1765,0.6863]`不是0到1.要么我误解,要么在这里有错误.你可以看到[我的回答](http://stackoverflow.com/a/26709885/1586200)处理类似的问题. (4认同)