Вот способ обрезать изображение всего его цвета фона в Python / OpenCV.
(Я не пытался оптимизировать или упростить код. Это просто демонстрация концепции. Например, вычисление 4 средних значений может быть преобразовано в функцию def, поскольку все они являются одни и те же строки кода повторяются для каждой стороны. Если кто-то переписывает код более эффективно или оптимизирует его, пожалуйста, сделайте повторную публикацию, чтобы другие могли извлечь выгоду. черный, а остальное белое, как маска. (Я использовал cv2.inRange (), чтобы для ввода можно было использовать цветное изображение.) Затем проверяется среднее значение каждой стороны маски толщиной в 1 пиксель, чтобы увидеть, не является ли она чисто-белой (255) и с какой стороны имеет самое низкое среднее (самое темное). Если не чистый белый цвет и не самая темная сторона, тогда увеличивайте / уменьшайте значение боковой координаты (как если бы эта строка или столбец удалялась, но не делала этого на самом деле). Продолжайте проверять внутренние строки и столбцы по бокам внутрь, пока все проверенные строки и столбцы не станут чисто белыми. Это чем-то похоже на чистку лука. Затем получите окончательные координаты сторон и обрежьте изображение.
Первое изображение:
import cv2
import numpy as np
# read image
img = cv2.imread('border_image1.jpeg')
#img = cv2.imread('border_image2.jpeg')
h, w = img.shape[:2]
# threshold so border is black and rest is white (invert as needed)
lower = (254,254,254)
upper = (255,255,255)
mask = cv2.inRange(img, lower, upper)
mask = 255 - mask
# define top and left starting coordinates and starting width and height
top = 0
left = 0
bottom = h
right = w
# compute the mean of each side of the image and its stop test
mean_top = np.mean( mask[top:top+1, left:right] )
mean_left = np.mean( mask[top:bottom, left:left+1] )
mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
mean_right = np.mean( mask[top:bottom, right-1:right] )
mean_minimum = min(mean_top, mean_left, mean_bottom, mean_right)
top_test = "stop" if (mean_top == 255) else "go"
left_test = "stop" if (mean_left == 255) else "go"
bottom_test = "stop" if (mean_bottom == 255) else "go"
right_test = "stop" if (mean_right == 255) else "go"
#print(top_test,left_test,bottom_test,right_test)
# iterate to compute new side coordinates if mean of given side is not 255 (all white) and it is the current darkest side
while top_test == "go" or left_test == "go" or right_test == "go" or bottom_test == "go":
# top processing
if top_test == "go":
if mean_top != 255:
if mean_top == mean_minimum:
top += 1
mean_top = np.mean( mask[top:top+1, left:right] )
mean_left = np.mean( mask[top:bottom, left:left+1] )
mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
mean_right = np.mean( mask[top:bottom, right-1:right] )
mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
#print("top",mean_top)
continue
else:
top_test = "stop"
# left processing
if left_test == "go":
if mean_left != 255:
if mean_left == mean_minimum:
left += 1
mean_top = np.mean( mask[top:top+1, left:right] )
mean_left = np.mean( mask[top:bottom, left:left+1] )
mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
mean_right = np.mean( mask[top:bottom, right-1:right] )
mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
#print("left",mean_left)
continue
else:
left_test = "stop"
# bottom processing
if bottom_test == "go":
if mean_bottom != 255:
if mean_bottom == mean_minimum:
bottom -= 1
mean_top = np.mean( mask[top:top+1, left:right] )
mean_left = np.mean( mask[top:bottom, left:left+1] )
mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
mean_right = np.mean( mask[top:bottom, right-1:right] )
mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
#print("bottom",mean_bottom)
continue
else:
bottom_test = "stop"
# right processing
if right_test == "go":
if mean_right != 255:
if mean_right == mean_minimum:
right -= 1
mean_top = np.mean( mask[top:top+1, left:right] )
mean_left = np.mean( mask[top:bottom, left:left+1] )
mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
mean_right = np.mean( mask[top:bottom, right-1:right] )
mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
#print("right",mean_right)
continue
else:
right_test = "stop"
# crop input
result = img[top:bottom, left:right]
# print crop values
print("top: ",top)
print("bottom: ",bottom)
print("left: ",left)
print("right: ",right)
print("height:",result.shape[0])
print("width:",result.shape[1])
# save cropped image
cv2.imwrite('border_image1_cropped.png',result)
#cv2.imwrite('border_image2_cropped.png',result)
# show the images
cv2.imshow("mask", mask)
cv2.imshow("cropped", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Обрезанное изображение:
Координаты кадрирования:
top: 132
bottom: 512
left: 3
right: 507
height: 380
width: 504
Второе изображение:
Обрезанное изображение:
Координаты культур:
top: 0
bottom: 420
left: 0
right: 512
height: 420
width: 512