Удаление только шаблона шахматной доски при чтении файла png в opencv python

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

import cv2
import numpy as np

input = cv2.imread('image.png')
ret, logo_mask = cv2.threshold(input[:,:,0], 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
cv2.imshow(logo_mask)

Входное изображение:

Выходное изображение:

Кто-нибудь может помочь?

Попробуйте использовать cv2.inRange дважды — один раз для белых пикселей и один раз для серых пикселей. Вы также можете игнорировать очень маленькие кластеры (найдите кластеры, используя findContours или connectedComponentsWithStats). Мы также можем искать белые кластеры, которые касаются серых кластеров, и серые кластеры, которые касаются белых кластеров.

Rotem 11.11.2022 10:32

Этот тип шаблона обычно используется программами для демонстрации прозрачности. Я полагаю, у вас нет исходного файла с отдельным альфа-каналом?

nick 11.11.2022 11:20

См. stackoverflow.com/questions/74134195/…

fmw42 11.11.2022 18:06
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Анализ продукта магазина на Tokopedia
Анализ продукта магазина на Tokopedia
Tokopedia - это место, где продавцы могут продавать свои товары. Товар должен быть размещен на витрине, чтобы покупателям было легче найти товар...
0
3
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Получение идеальных результатов, охватывающих все случаи, является сложной задачей.

В следующем решении предполагается, что белый цвет шахматной доски равен (255, 255, 255), а серый — (230, 230, 230).
Еще одно предположение состоит в том, что кластеры с такими цветами в других частях изображения очень малы.

Мы можем использовать следующие этапы:

  • Найдите «белую маску» и «серую маску», где цвет (255, 255, 255) и (230, 230, 230).
  • Создайте единую маску, используя побитовое или.
  • Найдите контуры и удалите мелкие контуры из маски (предполагается, что это «шум»).

Пример кода:

import cv2
import numpy as np

input = cv2.imread('image.png')

white_mask = np.all(input == 255, 2).astype(np.uint8)*255  # cv2.inRange(input, (255, 255, 255), (255, 255, 255))
gray_mask = np.all(input == 230, 2).astype(np.uint8)*255  # gray_mask = cv2.inRange(input, (230, 230, 230), (230, 230, 230))

mask = cv2.bitwise_or(white_mask, gray_mask)  # Create unified mask

ctns = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]  # Find contours

# Remove small contours from mask
for c in ctns:
    area = cv2.contourArea(c)  # Find the area of each contours
    if (area < 10):  # Ignore small contours (assume noise).
        cv2.drawContours(mask, [c], 0, 0, -1)

mask = cv2.dilate(mask, np.ones((3, 3), np.uint8))  # Dilate the mask - "cosmetics"

output = cv2.copyTo(input, 255-mask)  # Put black color in the masked part.

# Show images for testing
cv2.imshow('input', input)
cv2.imshow('mask', mask)
cv2.imshow('output', output)
cv2.waitKey()
cv2.destroyAllWindows()

white_mask:

gray_mask:

mask:

output:


Если на переднем плане есть большие белые или серые области, указанное выше решение может не сработать.

Я придумал процесс поиска только тех областей, которые перекрывают границу между белым и серым прямоугольниками.
Это не работает, потому что между ветвями дерева есть мелкие части, которые исключены.

Следующий код может вдохновить вас:

import cv2
import numpy as np

input = cv2.imread('image.png')
#ret, logo_mask = cv2.threshold(input[:,:,0], 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)

white_mask = np.all(input == 255, 2).astype(np.uint8)*255  # cv2.inRange(input, (255, 255, 255), (255, 255, 255))
gray_mask = np.all(input == 230, 2).astype(np.uint8)*255  # gray_mask = cv2.inRange(input, (230, 230, 230), (230, 230, 230))

cv2.imwrite('white_mask.png', white_mask)
cv2.imwrite('gray_mask.png', gray_mask)

# Apply opening for removing small clusters
opened_white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))
opened_gray_mask = cv2.morphologyEx(gray_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))

cv2.imwrite('opened_white_mask.png', opened_white_mask)
cv2.imwrite('opened_gray_mask.png', opened_gray_mask)

white_mask_shell = cv2.dilate(opened_white_mask, np.ones((3, 3), np.uint8)) - opened_white_mask  # Dilate white_mask and keep only the "shell"
gray_mask_shell = cv2.dilate(opened_gray_mask, np.ones((3, 3), np.uint8)) - opened_gray_mask # Dilate gray_mask and keep only the "shell"
white_mask_shell = cv2.dilate(white_mask_shell, np.ones((3, 3), np.uint8)) # Dilate the "shell"
gray_mask_shell = cv2.dilate(gray_mask_shell, np.ones((3, 3), np.uint8)) # Dilate the "shell"

cv2.imwrite('white_mask_shell.png', white_mask_shell)
cv2.imwrite('gray_mask_shell.png', gray_mask_shell)

overlap_shell = cv2.bitwise_and(white_mask_shell, gray_mask_shell)
cv2.imwrite('overlap_shell.png', overlap_shell)

dilated_overlap_shell = cv2.dilate(overlap_shell, np.ones((17, 17), np.uint8))

mask = cv2.bitwise_or(cv2.bitwise_and(white_mask, dilated_overlap_shell), cv2.bitwise_and(gray_mask, dilated_overlap_shell))

cv2.imshow('input', input)
cv2.imshow('white_mask', white_mask)
cv2.imshow('gray_mask', gray_mask)
cv2.imshow('white_mask', white_mask)
cv2.imshow('gray_mask', gray_mask)
cv2.imshow('opened_white_mask', opened_white_mask)
cv2.imshow('opened_gray_mask', opened_gray_mask)
cv2.imshow('overlap_shell', overlap_shell)
cv2.imshow('dilated_overlap_shell', dilated_overlap_shell)
cv2.imshow('mask', mask)
cv2.waitKey()
cv2.destroyAllWindows()

Вы можете добавить условие, что белые и серые области должны соприкасаться друг с другом, чтобы быть фоном.

Micka 12.11.2022 15:36

Код внизу делает это. Есть небольшие области, которые не охвачены.

Rotem 12.11.2022 17:10

Другие вопросы по теме