使用卷积矩阵模糊图像-伪影(Haskell) [英] Blurring Image with convolution matrices - artifacts (Haskell)

查看:62
本文介绍了使用卷积矩阵模糊图像-伪影(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆