Как обнаружить область больших # белых пикселей с помощью opencv?

Я хочу обнаружить логотип внутри изображения, чтобы удалить его, у меня есть идея, что для поиска объектов, у которых есть большое количество пикселей, затем удаляется, другая идея состоит в том, чтобы прорезать все белые пиксели (я инвертировал свой изображение) и искать пиксели, которые образуют большую область, а затем удалить эту область, есть ли какой-либо алгоритм лучше, чем этот, а также какие методы в opencv помогут мне обнаружить объект с большим числом пикселей.

Ответы

Ответ 1

У меня есть способ сделать это. Я не знаю, применим ли этот метод ко всем, но он работает хорошо.

Ниже приведен код (в Python):

Сначала преобразуйте изображение в оттенки серого, измените размер изображения, примените пороговое значение и сделайте изображение маски того же размера и типа изображения с уменьшенным размером в оттенках серого. (Изображение маски - просто черное изображение)

import cv2
import numpy as np

img = cv2.imread('bus.png')
img = cv2.resize(img,(400,500))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,gray = cv2.threshold(gray,127,255,0)
gray2 = gray.copy()
mask = np.zeros(gray.shape,np.uint8)

Теперь найдите контуры в пороговом изображении. Отфильтруйте контур для области от 500 до 5000. Это будет, скорее всего, большая белая капля, а не буквы. (Помните, что эта область особенно подходит для этого изображения. Я не знаю о ваших других изображениях. Вам нужно будет найти это самостоятельно). Теперь нарисуйте этот контур на изображении маски, заполненном белым цветом.

contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if 200<cv2.contourArea(cnt)<5000:
        cv2.drawContours(img,[cnt],0,(0,255,0),2)
        cv2.drawContours(mask,[cnt],0,255,-1)

Below is the detected contour image:

detected contour drawn on the input image

Next is the mask image:

New mask image

Теперь вы инвертируете изображение с помощью функции cv2.bitwise_not. Там у вас есть опция для предоставления маски, где мы даем изображение маски, чтобы функция работала только на области входного изображения, где в изображении маски есть белый.

cv2.bitwise_not(gray2,gray2,mask)

И, наконец, покажите изображение:

cv2.imshow('IMG',gray2)
cv2.waitKey(0)
cv2.destroyAllWindows()

И вот результат:

enter image description here


Примечание:

Вышеуказанный метод выполняется для сохранения "ORANGE" в белом квадрате. Вот почему есть некоторые артефакты. Если вы не хотите, чтобы этот оранжевый тоже, он может быть более точным.

Просто найдите ограничивающий прямоугольник для фильтров, отфильтрованных по площади, и нарисуйте прямоугольник, заполненный черным цветом.

Код:

import cv2
import numpy as np

img = cv2.imread('bus.png')
img = cv2.resize(img,(400,500))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,gray = cv2.threshold(gray,127,255,0)
gray2 = gray.copy()

contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if 200<cv2.contourArea(cnt)<5000:
        (x,y,w,h) = cv2.boundingRect(cnt)
        cv2.rectangle(gray2,(x,y),(x+w,y+h),0,-1)

cv2.imshow('IMG',gray2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Результат:

обнаружены ограничивающие прямоугольники:

enter image description here

Затем заполните эти прямоугольники черным:

enter image description here

Это лучше, чем предыдущий, конечно, если вы не хотите "ORANGE" )

Ответ 2

Вы можете использовать морфологические фильтры (возможно, чередующуюся последовательную фильтрацию), чтобы упростить многоцветное изображение, а затем использовать алгоритм сегментации, такой как водораздел или какой-то метод гранулометрии, и выбрать самый большой объект. Вы можете найти несколько реализаций в Интернете. Но это будет работать только в том случае, если логотип дискретный (например, не на фоне)