Полагаю, вы хотите сохранить merged_frame
, как показано cv2.imshow
.
Вы можете ограничить верхнее значение merged_frame
до 1
, масштабировать до 255
и преобразовать в тип uint8
перед сохранением:
merged_frame = np.round(np.minimum(merged_frame, 1)*255).astype(np.uint8)
Тип merged_frame
равно float64
.
При использовании cv2.imshow
для изображения типа float
все значения выше 1.0
являются белыми (а ниже 0
- черными).
Уровень серого в диапазоне [0, 1] эквивалентно диапазону [0, 255] типа uint8
(0,5 равно 128).
При использовании cv2.imwrite
изображение преобразуется в uint8
, но без ограничения и масштабирования (простое приведение к 255). Результат обычно очень темный.
Если вы хотите сохранить изображение, как показано, вам нужно ограничить значение до 1, а затем масштабировать до 255.
Вы не опубликовали ввод сэмплов, поэтому я создал синтети c вход:
import numpy as np
import cv2
background_subtractor = cv2.createBackgroundSubtractorMOG2(
history=30, varThreshold=50, detectShadows=False
)
width, height = 640, 480
frame = np.full((height, width), 60, np.uint8)
merged_frame = frame.astype(float)
for n in range(100):
img = np.full((height, width, 3), 60, np.uint8)
cv2.putText(img, str(n), (width//2-100*len(str(n)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20) # Green number
#frame = read_frame(cap)
frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
mask = background_subtractor.apply(frame, learningRate=0.01)
foreground = cv2.bitwise_and(frame, frame, mask=mask)
cv2.accumulateWeighted(foreground, merged_frame, 0.1)
cv2.imshow('Acccumulator', merged_frame)
cv2.waitKey(10)
#merged_frame = cv2.normalize(merged_frame, merged_frame, 0, 255.0, cv2.NORM_MINMAX).astype(np.uint8) # Alternative approch - normalize between 0 and 255
merged_frame = np.round(np.minimum(merged_frame, 1)*255).astype(np.uint8)
cv2.imshow('merged_frame as uint8', merged_frame)
cv2.imwrite('merged.png', merged_frame)
cv2.waitKey(0)
cv2.destroyAllWindows()
PNG-изображение с использованием imwrite
, без разбивки и масштабирования:
PNG изображение с использованием imwrite
, с кемпингом и масштабированием:
Лучший способ показать изображение - нормализовать значения для диапазона [0, 1] перед показом изображения.
Пример:
В л oop, после cv2.accumulateWeighted(foreground, merged_frame, 0.1)
:
norm_acccumulator = merged_frame.copy()
cv2.normalize(norm_acccumulator, norm_acccumulator, 0, 1.0, cv2.NORM_MINMAX)
cv2.imshow('Acccumulator', norm_acccumulator)