I'm trying to write code that will produce disparity maps using numpy and scipy, but the values that I store in my numpy array for my images are completely different from the values that are actually showing up in my output images, saved with misc.imsave. For example, in the array, none of the values are greater than 22, but in the image, I have a full range of values from 0 to 255. I thought that perhaps imsave was stretching the values so that the max value showed up as 255 in the image, but I have other images created with imsave that have a max below 255.
These are the functions I'm using to create my disparity maps, given two pgm images that have been shifted along the x axis:
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)
Ignore the SAD/SADstore return values, I have ensured that these are not effecting my current process.
This is the code I'm using to get my output:
disp12 = dispMap(9, view1, view2)
disp12im = disp12[0]
misc.imsave('disp121.pgm', disp12im)
As it current is, nothing in disp12im should be > 23. If I run a for loop to check this on the array, this remains true. However, if I load the saved image and run that same for loop on the values, I get tons of numbers over 23. What am I doing wrong?
The data gets rescaled when the dtype
of the array is changed from np.float64
(the data type of disp12im
) to the 8 bit values stored in the image.
To avoid this, convert your image to data type np.uint8
before giving it to imsave
:
misc.imsave('disp121.pgm', disp12im.astype(np.uint8))
For example, I'll save this x
as a PGM image:
In [13]: x
Out[13]:
array([[ 1., 3., 5.],
[ 21., 23., 25.]])
In [14]: x.dtype
Out[14]: dtype('float64')
Save x
unaltered, and then read it back:
In [15]: imsave('foo.pgm', x)
In [16]: imread('foo.pgm')
Out[16]:
array([[ 0, 21, 42],
[212, 234, 255]], dtype=uint8)
The values have been scaled up to the full 8-bit range.
Instead, convert x
to np.uint8
before saving, and then read it back:
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)
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