Как правильно использовать `cv2.imshow` для изображения с плавающей точкой, возвращаемого`cv2.distanceTransform`?
Что-то странное происходит с cv2.imshow. Я писал фрагмент кода и удивлялся, почему одна из моих операций не работала (что было выявлено при наблюдении cv2.imshow). В раздражении я записал то же самое изображение в файл, в котором оно выглядит хорошо. Почему cv2.imshow показывает двоичное изображение (первое изображение ниже), а cv2.imwrite записывает изображение в градациях серого как задумано (второе изображение)? У меня никогда не было проблем с отображением изображений в градациях серого!
cv2.imshow('Latest', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
distTransform = cv2.distanceTransform(src=image,distanceType=cv2.DIST_L2,maskSize=5)
cv2.imwrite('distanceTransform.png', distTransform)
cv2.imshow('Latest', distTransform)
cv2.waitKey(0)
cv2.destroyAllWindows()
Это изображение, отображаемое cv2.imshow:
Это изображение в том виде, в котором оно было сохранено с помощью imwrite:
1 ответ
При использовании cv2.imshow
, ты должен знать:
imshow(winname, mat) -> None
. The function may scale the image, depending on its depth:
. - If the image is 8-bit unsigned, it is displayed as is.
. - If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256.
That is, the value range [0,255\*256] is mapped to [0,255].
. - If the image is 32-bit or 64-bit floating-point, the pixel values are multiplied by 255. That is, the
. value range [0,1] is mapped to [0,255].
Функция distaceTransform
тип возврата float
, Поэтому, когда непосредственно отображается dist, сначала умножается на 255, а затем отображается на [0,255]. Так что результат так же, как двоичное изображение. (0*255=>0, 1*255=>255, ...*255=>255)
,
Для правильного отображения:
(1) вы можете обрезать float dist до [0,255] и изменить тип данных на np.uint8
от cv2.convertScaleAbs
dist1 = cv2.convertScaleAbs(dist)
(2) вы также можете нормализовать float dist до [0,255] и изменить тип данных на cv2.normalize
dist2 = cv2.normalize(dist, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
Вот пример с пандой:
Результат:
Полный код:
#!/ust/bin/python3
# 2018.01.19 10:24:58 CST
img = cv2.imread("panda.png", 0)
dist = cv2.distanceTransform(src=img,distanceType=cv2.DIST_L2,maskSize=5)
dist1 = cv2.convertScaleAbs(dist)
dist2 = cv2.normalize(dist, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
cv2.imshow("dist", dist)
cv2.imshow("dist1", dist1)
cv2.imshow("dist2", dist2)
cv2.waitKey()