Search code examples
pythonnumpynumpy-ndarray

Cropping a numpy.ndArray throws - ValueError: cannot write empty image as JPEG


I am trying to crop a numpy array image into smaller tiles and saving them: but when i try to save the tile i get an error that the image is empty.

My script takes into account excess pixels that does not reach the tile size and spread it out to the borders.

print("Slicing Image.")

path = 'Sliced/'
filename= 'sample_svs_2_'
img = tif.imread('sample_svs_2.svs')
print(type(img)) 
print(img.shape) 

#This works, proving that 
#this method of saving is valid
data = im.fromarray(img)
data.save('Sliced/sample.jpg') 


#depth, height, width  = img.shape
height, width, depth = img.shape
tilesize = 256

print("Height: ", height)
print("Width: ", width)
print("Depth: ", depth)

leftExcessPixels = int((width%tilesize)/2)
topExcessPixels = int((height%tilesize)/2)
XNumberOfTiles = int(width/tilesize)
YNumberOfTiles = int(height/tilesize)

print('Left Excess Pixels: ' + str(leftExcessPixels) )
print('Top Excess Pixels: ' + str(topExcessPixels) )

print('Number of X tiles: ' + str(XNumberOfTiles))
print('Number of Y tiles: ' + str(YNumberOfTiles))

for y in range(YNumberOfTiles):
    for x in range(XNumberOfTiles):
        XStart = (leftExcessPixels + (tilesize * x))
        YStart = (topExcessPixels + (tilesize * y))
        XEnd = XStart + tilesize
        YEnd = YStart + tilesize
        croppedImage = img[XStart:YStart, XEnd:YEnd] 
        data = im.fromarray(croppedImage)
        data.save('Sliced/sample_x' + str(x) + '_y' + str(y) + '.jpg') 

Terminal Output:

Slicing Image.
<class 'numpy.ndarray'>
(13271, 19992, 3)
Height:  13271
Width:  19992
Depth:  3
Left Excess Pixels: 12
Top Excess Pixels: 107
Number of X tiles: 78
Number of Y tiles: 51
Traceback (most recent call last):
  File "c:\fileImageSlicer.py", line 72, in <module>
    sliceImage()
  File "c:\fileImageSlicer.py", line 52, in sliceImage
    data.save('Sliced/sample_x' + str(x) + '_y' + str(y) + '.jpg')
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\miniconda3\Lib\site-packages\PIL\Image.py", line 2439, in save
    save_handler(self, fp, filename)
  File "C:\miniconda3\Lib\site-packages\PIL\JpegImagePlugin.py", line 647, in _save
    raise ValueError(msg)
ValueError: cannot write empty image as JPEG

What might i be doing wrong? one thing i totally ignored is the image being read has a z-dimension (depth?) im not sure why an image has a depth (maybe for color? RGB) , and im not sure how to use that..


Solution

  • The error is in line:

    croppedImage = img[XStart:YStart, XEnd:YEnd]
    

    The correct way of slicing the array should be:

    croppedImage = img[YStart:YEnd, XStart:XEnd]
    

    That way each of the cropped images have shape (256, 256, 3)