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


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

2 13

2 ответа:

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

Ниже приведен код (на 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:

обнаруженный контур, нарисованный на входном изображении

Next is the mask image:

Новое изображение маски

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

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

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

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

Введите описание изображения здесь


Примечание:

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

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

Код:

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()

Результат:

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

Введите описание изображения здесь

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

Введите описание изображения здесь

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

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