如何正确使用`cv2.imshow`为`cv2.distanceTransform`返回的浮点图像?

vhe*_*ssu 4 python opencv image-processing

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()
Run Code Online (Sandbox Code Playgroud)

这是cv2.imshow显示的图像: distancevnsform.png由cv2.imshow显示(也与输入图像相同)

这是由imwrite保存的图像: distancefnsform.png由imwrite编写

Kin*_*t 金 11

使用时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].
Run Code Online (Sandbox Code Playgroud)

函数distaceTransform返回类型float.因此,当直接显示dist时,它首先乘以255,然后映射到[0,255].所以结果就像二进制图像一样.(0*255=>0, 1*255=>255, ...*255=>255).

要正确显示:

(1)可以夹浮子DIST至[0255],改变的数据类型以np.uint8通过cv2.convertScaleAbs

dist1 = cv2.convertScaleAbs(dist)
Run Code Online (Sandbox Code Playgroud)

(2)你也可以将float dist标准化为[0,255]并改变数据类型 cv2.normalize

dist2 = cv2.normalize(dist, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
Run Code Online (Sandbox Code Playgroud)

这是熊猫的一个例子:

在此输入图像描述

结果:

在此输入图像描述


完整代码:

#!/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()
Run Code Online (Sandbox Code Playgroud)