0

I've been referred to How to crop an image in OpenCV using Python, but my question has a little difference.

This can be a numpy-slicing problem. I know I can do:

import cv2
img = cv2.imread("test_image.jpg")
crop_img = img[y:y+h, x:x+w]

But what if I need two rectangles with the same y range but non-consecutive x ranges of the original picture? I've tried:

crop_img = img[y:y+h, [x1:x1+w1, x2:x2+w2]]

What I expected was a rectangular having its height from y to y+h, and its width from x1 to x1+w1 plus x2 to x2+w2, where x1+w1 doesn't have to be equal to x2. Nevertheless I get a SyntaxError with "invalid syntax". Is there a way to correctly achieve my goal?

ytu
  • 1,822
  • 3
  • 19
  • 42

1 Answers1

2

You have to extract each part and then concatenate with the help of the concatenate function of numpy.

import numpy as np

v1 = img[y:y+h, x1:x1+w1]
v2 = img[y:y+h, x2:x2+w2]

v = np.concatenate((v1, v2), axis=1)

Or:

indexes = ((x1, w1), (x2, w2))
v = np.concatenate([img[y: y+h , v1: v1+v2] for v1,v2 in indexes], axis=1)

Another way:

Creating indexes as lists

v = img[y:y+h, list(range(x1, x1+w1)) + list(range(x2, x2 + w2))]
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Reminder `w1` must be equal to `w2` for this to work without getting `dtype=object` arrays (which will likely break any follow-on code). If they aren't you probably just want to output a list of `nD` subarrays instead of a `(n+1)D` array. – Daniel F May 03 '18 at 06:15