Cropping image by the center

14,352

Solution 1

You want to slice the first two axes of the numpy array, which correspond to height and width, respectively (the third is colour channel).

import matplotlib.pyplot as pl

# load image
img = pl.imread('my_image.png')

# confirm image shape
print(img.shape)

(218, 178, 3)

These three numbers correspond to the size of each axis, which for an image are usually interpreted as: (height, width, depth/colors).

# crop image
img_cropped = img[77:141, 57:121, :]

# confirm cropped image shape
print(img_cropped.shape)

(64, 64, 3)

Also note that when cropping, you could have also omitted the last colon: img[77:141, 57:121]

Solution 2

Cropping can be easily done simply by slicing the correct part out of the array. E.g. image[100:200, 50:100, :] slices the part between pixels 100 and 200 in y (vertical) direction, and the part between pixels 50 and 100 in x (horizontal) direction.

See this working example:

import matplotlib.pyplot as plt

mydic = {
  "annotations": [
  {
    "class": "rect",
    "height": 98,
    "width": 113,
    "x": 177,
    "y": 12
  },
  {
    "class": "rect",
    "height": 80,
    "width": 87,
    "x": 373,
    "y": 43
  }
 ],
   "class": "image",
   "filename": "https://i.stack.imgur.com/9qe6z.png"
}


def crop(dic, i):
    image = plt.imread(dic["filename"])
    x0 = dic["annotations"][i]["x"]
    y0 = dic["annotations"][i]["y"]
    width = dic["annotations"][i]["width"]
    height = dic["annotations"][i]["height"]
    return image[y0:y0+height , x0:x0+width, :]


fig = plt.figure()
ax = fig.add_subplot(121)
ax.imshow(plt.imread(mydic["filename"]))

ax1 = fig.add_subplot(222)
ax1.imshow(crop(mydic, 0))

ax2 = fig.add_subplot(224)
ax2.imshow(crop(mydic, 1))

plt.show()
Share:
14,352

Related videos on Youtube

Antonio López Ruiz
Author by

Antonio López Ruiz

I am currently a M.S. candidate in Data Science at Columbia University with an undergraduate degree in Applied Mathematics. My main programming languages are Python and R.

Updated on June 04, 2022

Comments

  • Antonio López Ruiz
    Antonio López Ruiz almost 2 years

    I have a PNG image of size 218, 178. I am using matplotlib's function imread to convert it into a ndarray. I would like to crop it to get the middle 64X64 part of the image.

    I tried cropping with np.reshape, but it makes no sense. I also tried slicing as a normal array, but I can't get it right since the actual array has a shape of (218,178,3). I want it (64,64,3) taking from 77 to 141 and 57 to 121 for the first two dimensions.

  • Antonio López Ruiz
    Antonio López Ruiz over 5 years
    Fixed, maybe a dictionary and a function are unnecessary
  • Antonio López Ruiz
    Antonio López Ruiz over 5 years
    I omitted the last colon, that was it. Thanks!
  • Bruno Ambrozio
    Bruno Ambrozio almost 5 years
    Didn't work for me: >>> import matplotlib.pyplot as pl >>> img = pl.imread('/Users/bambrozi/Downloads/tmp/12517.png') >>> print(img.shape) (49, 159, 3) >>> img_cropped = img[77:141, 57:121] >>> print(img_cropped.shape) (0, 64, 3)
  • benson
    benson almost 5 years
    Your image has a height of 49 pixels, so you cannot crop from pixel 77 to 141.