Вы можете использовать cv.boundingRect
, если не хотите использовать numpy np.nonzero
.
Кроме того, cv.boundingRect
быстрее numpy (возможно, потому что связывания C ++?).
image = np.array([[0,0,0,0,0], [0,0,1,2,0], [0,0,3,3,0], [0,0,0,0,0], [0,0,0,0,0]])
# the line below is usually not necessary when dealing with
# gray scale images opened with imread(), but you need it if
# you're working with the array created above, to get uint8 values
image = cv.convertScaleAbs(image)
x, y, w, h = cv.boundingRect(image)
newImg = image[y:y+h, x:x+w]
Время
В приведенном выше примере с массивом 5x5 cv.boundingRect
в 2 раза быстрее:
%timeit x, y = np.nonzero(image)
1.4 µs ± 219 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit x, y, w, h = cv.boundingRect(image)
722 ns ± 30.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
С Изображение 1000x1500, cv.boundingRect
намного быстрее (от 40x до 2000x, в зависимости от содержимого изображения):
# blank (all zero) image
image = np.zeros((1500,1000), dtype=np.uint8)
%timeit x, y = np.nonzero(image)
6.67 ms ± 40 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit x, y, w, h = cv.boundingRect(image)
159 µs ± 1.14 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# only non-zero pixels
image = np.ones((1500,1000), dtype=np.uint8)
%timeit x, y = np.nonzero(image)
17.2 ms ± 155 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit x, y, w, h = cv.boundingRect(image)
7.48 µs ± 46.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Numpy все еще достаточно быстро, если вы работаете только с одним изображением. Но, например, при обработке кадров живого видео все меняется.