使用卷积矩阵模糊图像-伪影(Haskell) [英] Blurring Image with convolution matrices - artifacts (Haskell)
问题描述
我正在尝试使用Haskell(使用JuicyPixels)进行一些图像处理.我已经完成了将高斯模糊应用于图像的功能,并且在处理后的图像中有一些奇怪的伪像:
I'm trying to do some image processing with Haskell (using JuicyPixels). I've done this function that apply Gaussian Blur to the image and there's some strange artifacts in processed image:
blur :: Image PixelRGBA8 -> Image PixelRGBA8
blur img@Image {..} = generateImage blurrer imageWidth imageHeight
where blurrer x y | x >= (imageWidth - offset) || x < offset
|| y >= (imageHeight - offset) || y < offset = whitePx
| otherwise = do
let applyKernel i j p | j >= matrixLength = applyKernel (i + 1) 0 p
| i >= matrixLength = p
| otherwise = do
let outPixel = pxMultNum
(pixelAt img (x + j - offset) (y + i - offset))
(gblurMatrix !! i !! j)
applyKernel i (j+1) (outPixel `pxPlus` p)
applyKernel 0 0 zeroPx
gblurMatrix = [[1 / 255, 4 / 255, 6 / 255, 4 / 255, 1 / 255],
[4 / 255, 16 / 255, 24 / 255, 16 / 255, 4 / 255],
[6 / 255, 24 / 255, 36 / 255, 24 / 255, 6 / 255],
[4 / 255, 16 / 255, 24 / 255, 16 / 255, 4 / 255],
[1 / 255, 4 / 255, 6 / 255, 4 / 255, 1 / 255]]
matrixLength = length gblurMatrix
offset = matrixLength `div` 2
whitePx = PixelRGBA8 255 255 255 255
zeroPx = PixelRGBA8 0 0 0 255
pxPlus :: PixelRGBA8 -> PixelRGBA8 -> PixelRGBA8
pxPlus (PixelRGBA8 r1 g1 b1 a1) (PixelRGBA8 r2 g2 b2 a2) = PixelRGBA8 (s r1 r2) (s g1 g2) (s b1 b2) 255
where s p1 p2 | p1 + p2 > 255 = 255
| p1 + p2 < 0 = 0
| otherwise = p1 + p2
pxMultNum :: PixelRGBA8 -> Double -> PixelRGBA8
pxMultNum (PixelRGBA8 r g b a) q = PixelRGBA8 (m r) (m g) (m b) (m a)
where m px = pxify $ fromIntegral px * q -- pxify is just synonym to function rounding a = (floor (a + 0.5))
这里是输入图像
并输出图片
Here are input image
and output image
看起来高斯模糊矩阵中系数为 1/256
的蓝色区域要少一些,但是如何彻底消除它们呢?
It looks like blueish areas are a bit less with 1/256
coefficient in Gaussian Blur Matrix, but how to get rid of them at all?
FIX:我想是因为 Pixel8
类型为0-255和Int,但是我只通过将内核中心的 36
更改为 35来解决了整个问题.
,因此(我认为)矩阵系数的总和为255/255 = 1.
FIX: I guess it's because of Pixel8
type 0-255 and Int, but I fixed whole thing just by changing 36
in the kernel center to 35
, so sum of matrix coefficients is (I believe) 255/255 = 1.
推荐答案
您写
| p1 + p2 > 255 = 255
| p1 + p2 < 0 = 0
防止溢出,但是这些条件永远都不成立. Word8
的值总是 在 0
和 255
之间.检查溢出的正确方法如下:
to protect against overflow, but these conditions are never true. Word8
values are always between 0
and 255
. A correct way to check for overflow looks like this:
| p1 + p2 < p1 = 255
但是最好还是首先避免溢出.我注意到,模糊矩阵的系数总计为 256/255
.也许您可以先解决该问题.
But better would be to avoid overflow in the first place. I note that your blur matrix's coefficients add up to 256/255
. Perhaps you could start by fixing that.
这篇关于使用卷积矩阵模糊图像-伪影(Haskell)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!