【问题标题】:How to get the noise based on the original image and denoised image?如何根据原始图像和去噪图像获得噪声?
【发布时间】:2021-07-14 12:31:12
【问题描述】:

我正在做去噪工作,我对 Python 不是很熟悉。我用BM3D得到去噪的图片,我也有原图。

现在我想通过这样做来消除噪音:

tmp = img - img_denoised

但原来是这样一个很奇怪的黑白图:

那么我怎样才能得到一张合适的噪点图片呢?我希望得到的是这样的图像:

编辑: 从网上找了一张图片,做了同样的处理。

处理后:

再次编辑:

提供一个简单的例子:

import cv2

img = cv2.imread("path of the original image")

img_denoised = cv2.imread("path of the denoised image")

tmp = img - img_denoised

cv2.imwrite("test_noise.jpg",tmp)

【问题讨论】:

  • @Bilal 抱歉,使用网络上传图片可能会有些麻烦...由于我有去噪图像和原始图像,如何获取噪声图像与实际关系不大我认为的图像。
  • 确实如此。但是您仍然可以发布minimal reproducible example:拍摄任何其他图像,添加一些噪声,将差异作为您的噪声图像,显示它。我认为您对图像的显示方式有疑问,但也可能是类型的问题。
  • 再次,请显示minimal reproducible example。我们不需要查看您的去噪代码,编写一个简短的程序来加载您刚刚发布的那两张图像,获取差异并显示结果。这样我们就可以看到你是如何做这些事情的。确保您的示例程序重现了该问题。
  • @Cris Luengo 我更新了一个简单的例子,也许有帮助?

标签: python image-processing


【解决方案1】:

在您的示例代码中,imgimg_denoised 都是 uint8 NumPy 数组。对这些数组进行操作时,输出的类型相同。这些运算都是以 256 为模的。当运算结果超过 255 时,它会回绕回 0,当结果为负时,它会回绕回 255。例如:

np.array([5], np.uint8) - np.array([10], np.uint8)

返回array([251], dtype=uint8)。我们得到 256 - 5 = 251,而不是 -5,它不能用 uint8 值表示。

减法img - img_denoised 会产生一些略高于零的值,看起来黑色,而一些值略低于零,将存储为接近 255 的值并看起来白色。

我们可以通过不同的方式解决这个问题。一种是强制使用浮点值进行操作:

tmp = img.astype(float) - img_denoised.astype(float)

我们现在有一个浮点数组,其中大约一半是负数。但是 JPEG 文件只能存储 uint8 值,将浮点值转换为 uint8 将使我们回到开始的位置。所以我们需要把原点(零值)移到一个中间灰色(一般是128):

tmp = img.astype(float) - img_denoised.astype(float)
tmp += 128
cv2.imwrite("test_noise.jpg", tmp.astype(np.uint8))

这是非常繁琐的,但它确实有效。我更喜欢使用一个为我处理数据类型的库,所以当我不想时不必考虑它们。 DIPlib就是这样一个库(免责声明:我是作者):

import diplib as dip

img = dip.ImageRead("7yJS3.png")
img_denoised = dip.ImageRead("xjQIy.png")

tmp = img - img_denoised
tmp += 128
dip.ImageWrite(tmp, "test_noise.jpg")

在 DIPlib 中,算术运算会自动将图像提升为浮点类型,除非我们明确禁止它。另存为 JPEG 会静默地将图像转换为 uint8(如果像素值超出 uint8 类型的范围,则会发生错误)。

【讨论】:

  • 非常感谢!它解决了我的问题,现在我可以获得正确的图像!
【解决方案2】:

由于信息有限,很难确定问题所在。请提供输入图片和更多代码。

看起来结果图像是二进制位图,只有白色或黑色,没有灰色。您的 tmp 图像的像素格式可能不正确,这可能是由于您的 img 和 img_denoised 的像素格式不同,或者两者都是错误的。尝试显示您的输入图像,看看它们是否正常。

你的 img 和 img_denoised 应该是相同的像素格式,可能是 8 位灰度,也可能是 24 位 RGB,在img-img_denoised 之后,结果应该仍然是相同的像素格式。

也可能是因为它没有签名,试着让它签名,或者对所有像素 + 128 看看发生了什么。

【讨论】:

  • 感谢您的回答。我更新了问题,不知道是否提供了足够的信息。 BM3D算法也比较复杂,不知道要放多少代码。
  • 如果您无法回答问题,请不要发布答案。您可以发表评论以要求澄清,也可以标记问题以供审核。
【解决方案3】:

您的图像数据类型/范围是什么? 0-1 还是 0-255?

如果你的图像是0-1 float32,则噪声图像的数据范围为[-1, 1],大约一半的像素低于0,并且当cv2.imshow()显示为“黑色”时。

试试

noise = origin - clean
noise = (noise + 1) * 0.5

【讨论】:

  • 感谢您的回答!我试过你的方法,但结果是黑色和灰色的图像......但也许是类型的问题?稍后我会弄清楚的。
猜你喜欢
  • 2023-04-05
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
  • 2014-05-22
  • 1970-01-01
  • 2016-12-13
相关资源
最近更新 更多