Чтобы понять, почему ваши изображения получаются черно-белыми, давайте пройдемся по коду.
resized_masks = np.empty([masks.shape[0], monitor_h, monitor_w, masks.shape[3]])
Эта строка по умолчанию создает массив типа np.float
.
resized_masks[i] = cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h))
Эта строка присваивает результат cv2.resize
срезу resized_masks
.
Ваши исходные изображения и, следовательно, результат cv2.resize
, предположительно, имеют тип np.uint8
. Присвоение преобразует значения в float
s для помещения их в буфер. Актерский состав хорош сам по себе: 5
конвертируется в 5.0
, 255
конвертируется в 255.0
. Проблема в том, что значения float
интерпретируются как обрезанные до диапазона [0.0, 1.0]
, а не [0.0, 255.0]
. Таким образом, в результате получаются изображения, которые фактически являются всеми нулями и единицами, даже если они содержат то, что выглядит как правильные значения.
Вы можете проверить правильность значений, отобразив
resized_masks.astype(masks.dtype)
Это не настоящее исправление. Реальное исправление состоит в том, чтобы начать с правильного типа вывода:
resized_masks = np.empty((masks.shape[0], monitor_h, monitor_w, masks.shape[3]), dtype=masks.dtype)
Обратите внимание, что принято использовать кортежи для фигур, а не списков, но это не имеет значения функционально.
Теперь давайте посмотрите, почему ваш патч сработал.
resized_masks = list(resized_masks)
Это создает список ссылок Python для каждого подмассива. Поскольку вы действительно выполняете нарезку, они все равно будут указывать на непрерывный буфер под капотом, но важно то, что каждый resized_masks[i]
является отдельной ссылкой, а не срезом в один и тот же объект массива.
resized_masks[i] = list(cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h)))
Поскольку resized_masks
является списком, содержащим ссылки, теперь он присваивает результат cv2.resize
элементу списка i
, а не назначает содержимое в срез соответствующего размера. Здесь вам не нужна оболочка list
, поскольку она вводит ненужное измерение.
resized_masks = np.asarray(resized_masks)
Это просто объединяет список в массив, так как все элементы имеют правильный размер (хотя вы будете см. дополнительную единицу измерения, как указано выше). Как вы можете себе представить, это решение крайне неэффективно. Помимо того, что вы переходите в списки и из них и выделяете несколько ненужных буферов, вы также отбрасываете оригинальный массив np.empty
без его использования.
Ваш патч примерно эквивалентен выполнению
resized_masks = np.array([cv2.resize(np.copy(mask), (monitor_w, monitor_h)) for mask in masks])
Я не рекомендую так делать.