Изображение, которое должно быть черно-белым, имеет промежуточные значения и не может использоваться в качестве двоичной маски

#python #image #opencv #image-processing #python-imaging-library

Вопрос:

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

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

Однако при чтении с помощью opencv через:

 img = cv2.imread("myImage.png", cv2.IMREAD_UNCHANGED)
 

Мы замечаем, что его значения различаются:

например

 array([  0,  16,  32,  48,  64,  79,  80,  95,  96, 111, 112, 127, 128,
   143, 144, 159, 160, 175, 176, 191, 192, 207, 208, 223, 224, 239,
   240, 255], dtype=uint8)
 

Есть ли безопасный способ преобразовать его в простой двоичный диапазон ([0,1])?
Для использования пакета нет ограничений, это может быть либо opencv, либо pillow и т.д.

Комментарии:

1. как насчет простой пороговой операции? docs.opencv.org/4.5.1/d7/d4d/tutorial_py_thresholding.html

2. это можно сделать с numpy.where помощью и ничего больше

Ответ №1:

RGB-канал вашего изображения-это все нули, разница в цвете в альфа-канале

Получить Альфа-канал

 img = cv2.imread("myImage.png", cv2.IMREAD_UNCHANGED)
img_alpha = img[:,:,3]
 

Преобразование альфа — канала в двоичный

 thresh = 127
im_bw = cv2.threshold(img_alpha, thresh, 255, cv2.THRESH_BINARY)[1]
 

Диапазон в [0,1]

 im_bw = im_bw // 255
 

Ответ №2:

Вы можете определить пороговое значение, например 127. Затем определите значения пикселей ниже порогового значения как ноль и выше порогового значения как 1. Но я думаю, что у вас есть еще одна проблема, потому что значения вашего изображения имеют широкий диапазон (от 0 до 255). Это не соответствует изображению, которое вы показываете.

Ответ №3:

Ваше изображение имеет альфа-канал и прозрачность

 import sys
import cv2
import numpy as np

dir = sys.path[0]
im = cv2.imread(dir '/img.png', -1)

im[np.where(im[:, :, 3] == 0)] = (255, 255, 255, 255)
cv2.imwrite(dir '/img_without_transparency.png', im)

im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

min = np.min(im)
max = np.max(im)
bw = cv2.threshold(im, (min max)//2, 255, cv2.THRESH_BINARY)[1]
print(np.min(bw), np.max(bw))  # 0-255

bw = bw/255
print(np.min(bw), np.max(bw))  # 0-1
 

Так что белое пространство на самом деле не белое:

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