20

So I have an 800 x 600 image that I want to cut vertically into two equally sized pictures using OpenCV 3.1.0. This means that at the end of the cut, I should have two images that are 400 x 600 each and are stored in their own PIL variables.

Here's an illustration:

Paper being cut into halves

Thank you.

EDIT: I want the most efficient solution so if that solution is using numpy splicing or something like that then go for it.

Elliot Killick
  • 389
  • 2
  • 4
  • 12

3 Answers3

20

You can try the following code which will create two numpy.ndarray instances which you can easily display or write to new files.

from scipy import misc

# Read the image
img = misc.imread("face.png")
height, width = img.shape

# Cut the image in half
width_cutoff = width // 2
s1 = img[:, :width_cutoff]
s2 = img[:, width_cutoff:]

# Save each half
misc.imsave("face1.png", s1)
misc.imsave("face2.png", s2)

The face.png file is an example and needs to be replaced with your own image file.

fsimkovic
  • 1,078
  • 2
  • 9
  • 21
  • 1
    Thanks for the answer. The only thing I got rid of is the third variable/index on line: `height, width, _ = img.shape`, `s1 = img[:, :width_cutoff, :]` and `s2 = img[:, width_cutoff:, :]` Since an image is 2D and the program gave me an error until I removed those. – Elliot Killick Jul 29 '17 at 13:34
  • I also tried using `width = len(img[0])` to see if that would find the width faster just in case but numpy prevailed. Timeit Times: Numpy Splicing: `0.18052252247208658` len(): `0.2773668664358264` – Elliot Killick Jul 29 '17 at 13:49
  • @Halp Could you cut the image in half? I want to do the same, but I have this error. https://pt.stackoverflow.com/questions/343680/erro-ao-dividir-imagem-ao-meio-usando-python – Carlos Diego Nov 15 '18 at 18:41
4
import cv2   
# Read the image
img = cv2.imread('your file name')
print(img.shape)
height = img.shape[0]
width = img.shape[1]

# Cut the image in half
width_cutoff = width // 2
s1 = img[:, :width_cutoff]
s2 = img[:, width_cutoff:]

cv2.imwrite("file path where to be saved", s1)
cv2.imwrite("file path where to be saved", s2)
2

you can define following function to simply slice every image you want to two vertical parts.

def imCrop(x):
    height,width,depth = x.shape
    return [x[height , :width//2] , x[height, width//2:]]

and then you can simply for example plot the right part of the image by:

plt.imshow(imCrop(yourimage)[1])
eyllanesc
  • 235,170
  • 19
  • 170
  • 241