Обрезка урожая в цветной коробке - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть изображение, как показано ниже. Мне нужно определить «зеленую» рамку и часть обрезки изображения как отдельное изображение.

Я могу использовать только numpy & opencv

Я просмотрел несколько постов, но я Я не в состоянии понять это. Может кто-нибудь помочь. Основываясь на результатах поиска, я предполагаю, что для этого нужно использовать какую-то маску. Если да, пожалуйста, предоставьте некоторую информацию о том, как выбрать значения для определенного цвета. Я видел, что выбор значения цвета сам по себе является огромной топи c, но я сам не могу понять это. Любое руководство я оценил.

enter image description here

1 Ответ

1 голос
/ 28 февраля 2020

Вы можете найти все зеленые пиксели, найти контуры и обрезать ограничивающий прямоугольник найденного контура:

  • Гель всех зеленых пикселей на изображении, где RGB = (0, 255 , 0):

    green_pix = np.all(img == (0, 255, 0), 2)
    
  • Преобразовать green_pix в uint8 двоичное изображение со значениями 0 и 255:

    thresh_gray = green_pix.astype(np.uint8)*255
    
  • Найти контуры в thresh_gray:

    contours, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    
  • Получить прямоугольник и обрезать прямоугольник

    out = img[y:y+h, x:x+w, :]
    

Вот пример рабочего кода:

import numpy as np
import cv2

# (cv_major_ver, cv_minor_ver, cv_subminor_ver) = (cv2.__version__).split('.')  # Get version of OpenCV

img = cv2.imread('green_box.png')

# Gel all green pixels in the image - where RGB = (0, 255, 0)
green_pix = np.all(img == (0, 255, 0), 2)

# Convert green_pix to uint8 binary image with values 0 and 255
thresh_gray = green_pix.astype(np.uint8)*255 

# Find contours in thresh_gray.
# if int(cv_major_ver) < 4:
#     _, contours, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# else:
#     contours, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

contours = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]  # Shortcut (get index [-2] instead of using if-else).

# Get rectangle (assume there is only one contour)
x, y, w, h = cv2.boundingRect(contours[0])

# Crop rectangle
out = img[y:y+h, x:x+w, :]

cv2.imwrite('out.png', out)  #Save out to file (for testing).

# Show result (for tesing).
cv2.imshow('out', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

Результат:
enter image description here


Обновление:

У меня есть более простое решение:

  • Поиск индексов зеленых пикселей.
  • Получение минимального и максимального индекса по обеим осям.
  • Обрезать прямоугольник.

Вот код :

# Find indices of green pixels.
idx = np.where(np.all(img == (0, 255, 0), 2))

# Get minimum and maximum index in both axes (top left corner and bottom right corner)
x0, y0, x1, y1 = idx[1].min(), idx[0].min(), idx[1].max(), idx[0].max()

# Crop rectangle
out = img[y0:y1+1, x0:x1+1, :]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...