You are a bit off calculating the range of the for loop. The number of slices that need to be done should be calculated using the offset between the two slices, which in your case x0/2 , I simplified your code and defined some significant variables that you can configure to get the desired slices from the 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 the current offset, if the exact multiple is the size of the image, which is 512x512, therefore, we get 4 tiles of the same size:

By changing the offset value, you will get tiles of the wrong size, if the offset, if it is not exact, is a multiple of the image size, later you can filter these fragments if it is not necessary, changing math.ceil to math.floor in for .
source share