Skip to main content
comment on the exceptional case
Source Link
Gareth Rees
  • 49.7k
  • 3
  • 129
  • 210

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole image.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min(axis=0)
x1, y1 = coords.max(axis=0) + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]

(Note that this relies on there being some non-black pixels; if the whole image is black, then coords will be empty and you'll have to find something else to do in that case.)

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole image.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min(axis=0)
x1, y1 = coords.max(axis=0) + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole image.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min(axis=0)
x1, y1 = coords.max(axis=0) + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]

(Note that this relies on there being some non-black pixels; if the whole image is black, then coords will be empty and you'll have to find something else to do in that case.)

edited body
Source Link
Gareth Rees
  • 49.7k
  • 3
  • 129
  • 210

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole arrayimage.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min(axis=0)
x1, y1 = coords.max(axis=0) + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole array.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min()
x1, y1 = coords.max() + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole image.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min(axis=0)
x1, y1 = coords.max(axis=0) + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]
Source Link
Gareth Rees
  • 49.7k
  • 3
  • 129
  • 210

As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole array.

In this case, you could use numpy.argwhere to find the bounding box of the non-black regions:

# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0

# Coordinates of non-black pixels.
coords = np.argwhere(mask)

# Bounding box of non-black pixels.
x0, y0 = coords.min()
x1, y1 = coords.max() + 1   # slices are exclusive at the top

# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]