scipy imsave保存错误的值

jac*_*ise 5 python numpy scipy

我正在尝试编写使用numpy和scipy生成视差图的代码,但是我在我的numpy数组中存储的值与我的输出图像中实际显示的值完全不同,用misc保存. imsave.例如,在数组中,没有一个值大于22,但在图像中,我有一个从0到255的全范围值.我认为也许imsave正在拉伸值,以便最大值显示为图像中有255个,但我有其他使用imsave创建的图像,其最大值低于255.

这些是我用来创建视差图的函数,给定了两个沿x轴移动的pgm图像:

def disp(i, j, winSize, leftIm, rightIm): #calculate disparity for a given point
    width = leftIm.shape[1]
    height = leftIm.shape[0]
    w = winSize / 2
    minSAD = 9223372036854775807 #max int
    for d in range(23):
        SAD = 0.0 #SAD
        k = i - w
        v = i + w
        m = j - w
        n = j + w
        for p in range(k, v+1): #window - x
            for q in range(m, n+1): #window y
                if(p - d > 0 and p < width and q < height):
                    SAD += abs((int(leftIm[q][p]) - int(rightIm[q][p - d])))
        if(SAD < minSAD):
            minSAD = SAD
            disp = d
    #       print "%d, %d" % (i, j)
    return (disp, SAD)

def dispMap(winSize, leftIm, rightIm):
    width = leftIm.shape[1]
    height = leftIm.shape[0]
    outIm = np.zeros((height, width)) 
    SADstore = np.zeros((height, width))
    w = winSize / 2
    for i in range(w, width-w):
        for j in range(w, height/3-w):
            dispout =  disp(i, j, winSize, leftIm, rightIm)
            outIm[j][i] = 1 * dispout[0] #should normally multiply by 4
            SADstore[j][i] = dispout[1]
    return (outIm, SADstore)
Run Code Online (Sandbox Code Playgroud)

忽略SAD/SADstore返回值,我确保这些不会影响我当前的进程.

这是我用来获取输出的代码:

disp12 = dispMap(9, view1, view2)
disp12im = disp12[0]
misc.imsave('disp121.pgm', disp12im)
Run Code Online (Sandbox Code Playgroud)

就目前而言,disp12im中的任何内容都不应超过23.如果我运行for循环来检查数组,这仍然是正确的.但是,如果我加载保存的图像并在值上运行相同的循环,我会得到大于23的数字.我做错了什么?

War*_*ser 5

当dtype数组的值从np.float64的数据类型更改disp12im为图像中存储的8位值时,数据将重新缩放。

为避免这种情况,请在将图像np.uint8提供给之前将其转换为数据类型imsave:

misc.imsave('disp121.pgm', disp12im.astype(np.uint8))
Run Code Online (Sandbox Code Playgroud)

例如,我将其另存x为PGM图像:

In [13]: x
Out[13]: 
array([[  1.,   3.,   5.],
       [ 21.,  23.,  25.]])

In [14]: x.dtype
Out[14]: dtype('float64')
Run Code Online (Sandbox Code Playgroud)

保存x未更改,然后将其读回:

In [15]: imsave('foo.pgm', x)

In [16]: imread('foo.pgm')
Out[16]: 
array([[  0,  21,  42],
       [212, 234, 255]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)

这些值已放大到整个8位范围。

相反,在保存之前转换x为np.uint8,然后将其读回:

In [17]: imsave('foo.pgm', x.astype(np.uint8))

In [18]: imread('foo.pgm')
Out[18]: 
array([[ 1,  3,  5],
       [21, 23, 25]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)