如何解决为什么 cv2.bilateralFilter 对于不同的数据类型表现如此不同?
正如标题所述,为什么 cv2.bilateralFilter
对于不同的 dtype 表现如此不同?
文档说,cv2.bilateralFilter
仅适用于 np.float32
或 np.uint8
dtype。但是当我将它应用于我的图像时,两种 dtype 的输出看起来大不相同。
我正在使用 skimage 函数 img_as_x
在数据类型之间进行转换,因为我听说在处理图像时必须从不使用 .astype(x)
。所以我的代码看起来像这样:
Radargram = img_as_float32(cv2.imread(image)[:,:,::-1])
CropRadGram = (Radargram[700:2450,:])[:,0]
SigmaAll = 10
RadGramFilter = cv2.bilateralFilter(img_as_ubyte(CropRadGram),-1,SigmaAll,SigmaAll) #As uint8
RadGramFilter2 = cv2.bilateralFilter(CropRadGram,SigmaAll) #as float32
plt.figure(figsize=(20,20)); plt.imshow(RadGramFilter,cmap='gray')
plt.figure(figsize=(20,20)); plt.imshow(RadGramFilter2,cmap='gray')
RadGramFilterImg = Image.fromarray(img_as_ubyte(RadGramFilter)) #Transform to uint8 and construct image
RadGramFilterImg.save(f'Prepared_CropGrams/{IMG_nr}_RAD_prepared.png') #Save the image
RadGramFilter
和 RadGramFilter2
的输出可以在这里看到:
谢谢
解决方法
[...] 因为我听说在处理图像时必须从不使用 .astype(x)
。
这在很大程度上取决于使用的库和用例!在这个非常具体的示例中,首先使用 img_as_float32
而不是 .astype(np.float32)
会导致观察到的行为!
查看有关 cv2.bilateralFilter
的文档,我们看到有一个参数 sigmaColor
,您将其设置为 20
,用于与 np.uint8
和 { {1}} 个图像。但是,np.float32
仅适用于此处的 sigmaColor = 20
情况,因为它的值在 np.uint8
的范围内。另一方面,您的 [0 ... 255]
图像具有 np.float32
范围内的值,这解释了严重模糊。
因此,有两个选项可以解决该问题,均涉及手动缩放:
- 在开头使用
[0.0 ... 1.0]
。然后,您可以使用.astype(np.float32)
,但您生成的图像的值将在sigmaColor = 20
范围内,因此您需要除以0.0 ... 255.0
,例如在使用255
绘图之前。
matplotlib
- 在
import cv2 import matplotlib.pyplot as plt import numpy as np from skimage import img_as_float32,img_as_ubyte # Use .astype(x) instead of img_as_x img = cv2.imread('path/to/your/image.jpg')[...,::-1] filter_uint8 = cv2.bilateralFilter(img,200,200) filter_float32 = cv2.bilateralFilter(img.astype(np.float32),200) plt.figure(1,figsize=(14,8)) plt.subplot(2,2,1),plt.imshow(img),plt.title('Original image') plt.subplot(2,2),plt.imshow(filter_uint8),plt.title('uint8 filtered') plt.subplot(2,3),plt.imshow(filter_float32),plt.title('float32 filtered') plt.subplot(2,4),plt.imshow(filter_float32 / 255),plt.title('float32 filtered,corrected') plt.tight_layout()
调用中将sigmaColor
除以255
。因此,您的结果将直接具有cv2.bilateralFilter
范围内的值:
0.0 ... 1.0
import cv2
import matplotlib.pyplot as plt
from skimage import img_as_float32,img_as_ubyte
# Scale sigmaColor w.r.t. to float value range of [0.0 ... 1.0]
img = img_as_float32(cv2.imread('path/to/your/image.jpg')[...,::-1])
filter_uint8 = cv2.bilateralFilter(img_as_ubyte(img),200)
filter_float32 = cv2.bilateralFilter(img,200)
filter_float32_corr = cv2.bilateralFilter(img,200/255,200)
plt.figure(0,plt.imshow(filter_float32_corr),corrected')
plt.tight_layout(),plt.show()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。