I am using numpy to create tiles of (224*224) from my 16-bit tiff image (13777*16004). I was able to crop/slice into equal tiles of 224*224 along the rows and columns. I ran into problems while trying to create new tiles shifting by half of the tile size... For instance: A rough algorithm of what i am trying to achieve
(1:224, 1:224)
(1:224, 112:336)
( , 224:448)
The goal is to retain tile size (224*224) while shifting by half of tile size to obtain more image tiles...
Snippet of code written to perform task
row_x = img.shape[0]
column_y = img.shape[1]
tile_size_x = 224
tile_size_y = 224
range_x = mpz(ceil(row_x/tile_size_x))
range_y = mpz(ceil(column_y/tile_size_y))
for x in range(range_x, row_x):
for y in range(range_y, column_y):
x0 = x * tile_size_x
x1 = int(x0/2) + tile_size_x
y0 = y * tile_size_y
y1 = int(y0/2) + tile_size_y
z = img[x0:x1, y0:y1]
print (z.shape,z.dtype)
I keep getting wrong results, can anyone help ???
解决方案
You went a little off while calculating the range of your for loop. The number of slices to be made, must be calculated using the offset between two slices, which is x0/2 in your case, I have simplified your code and defined some meaningful variables which you can configure to get desired tiles from a given image:
import cv2
import math
img = cv2.imread("/path/to/lena.png") # 512x512
img_shape = img.shape
tile_size = (256, 256)
offset = (256, 256)
for i in xrange(int(math.ceil(img_shape[0]/(offset[1] * 1.0)))):
for j in xrange(int(math.ceil(img_shape[1]/(offset[0] * 1.0)))):
cropped_img = img[offset[1]*i:min(offset[1]*i+tile_size[1], img_shape[0]), offset[0]*j:min(offset[0]*j+tile_size[0], img_shape[1])]
# Debugging the tiles
cv2.imwrite("debug_" + str(i) + "_" + str(j) + ".png", cropped_img)
As current offset if exact multiple of image dimensions, which is 512x512, hence we will get 4 tiles of same size:
Changing the value of offset, would get you tiles of irregular size, if the offset if not exact multiple of the image dimensions, you may later filter those tiles if not required by changing the math.ceil to math.floor in the for loop.