skimage resize giving weird output

2019-06-22 19:20发布

问题:

I'm resizing an image using skimage.transform.resize but I'm getting a really weird output and I can't figure out why. Can anyone help?

Here is my code:

import matplotlib.pyplot as plt
import skimage.transform
plt.imshow(y)
h,w,c = y.shape
x = skimage.transform.resize(y, (256, (w*256)/h), preserve_range=True)
plt.imshow(x)

Here is my input image y (240, 320, 3):

Here is my output image x (256, 341, 3):

Edit: Okay it seems to work fine if I change preserve_range=False. But why won't it allow me to keep the current range?

Edit: I'm randomly sampling frames from videos using OpenCV. Here's the function that returns a frame from the video path I pass to it.

def read_random_frames(vid_file):

   vid = cv2.VideoCapture(vid_file)
   # get the number of frames    
   num_frames = vid.get(cv2.CAP_PROP_FRAME_COUNT)
   # randomly select frame
   p_frame = random.randint(0, (num_frames-1))
   # get frame
   vid.set(cv2.CAP_PROP_POS_FRAMES, p_frame)
   ret, frame = vid.read()
   # convert from BGR to RGB
   frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

   return frame

I have a list of video paths and I use a map function to retrieve the frames then I convert the outputed list to a numpy array:

 batch_frames = map(lambda vid: read_random_frames(vid), train_vids_batch)
 frame_tensor = np.asarray(batch_frames)
 y = frame_tensor[0]

回答1:

I think it is simply because by preserving the range I end up with a float in the range [0, 255] whereas pyplot.imshow is only capable of displaying MxNx3 float arrays in the range [0.0, 1.0]. When I convert the output to an uint8 using z = np.copy(x).astype('uint8') it displays fine.



回答2:

  1. As @RHankins mentioned, plt.imshow can display either float images with pixels within range [0.0, 1.0] or integer images with pixels within range [0, 255].

  2. skimage.transform.resize calls a function wrap (_warps.py#L161) which always converts an input image to float64 (_warps.py#L797).

That's why you always need to convert the output to whatever you prefer. For example to resize image and get np.uint8 output image within range in [0, 255] you do:

import matplotlib.pyplot as plt
from skimage import img_as_ubyte
import skimage.transform
x = img_as_ubyte(skimage.transform.resize(y, (100, 100)))
plt.imshow(x)


回答3:

Can you please provide a full example? How do you read your image data, what is the original format? (Using y = scipy.misc.imread("somefile.png") on a .png-file it works perfectly on my machine)

What is the data-type (and ndarray.dtype) of your data?

import matplotlib.pyplot as plt
import skimage.transform
from scipy.misc import imread

y = imread("tree.png")

plt.subplot(121)
plt.imshow(y)
h,w,c = y.shape
x = skimage.transform.resize(y, (256, (w*256)//h), preserve_range=True)
plt.subplot(122)
plt.imshow(x)
plt.show()