试图用C ++“模糊”矩阵;有缺陷的算法或代码?

问题描述 投票:1回答:2

问题

我正在尝试使用koef“模糊”一个矩阵(就像你的图像一样)(见下文)并且它不按照我想要的方式工作。我通过.txt文件提供矩阵。

什么是koef?

This site很好地解释了它是如何工作的。对于这种模糊我使用“模糊光”,其中koef为14,它是以下3x3矩阵(代表模糊密度)的总和:

1 2 1
2 2 2
1 2 1

这可能是一种更简单的方法,而不是硬编码相同的东西九次。我还有手绘的图表,表示循环/条件结构以及它们实际正在做什么,如果这将是有用的。

void blur(int pic[][MAX_COL]/*OUT*/, int height, int width)
{
    int newPic[MAX_ROW][MAX_COL] = {0};

    for (int h = 0; h < height; h++)
    {
        for (int w = 0; w < width; w++)
        {
            if (h == 0 && w == 0)
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w-1] + 2 * pic[h+1][w] + 1 * pic[h+1][w-1])
                                /(pic[h][w] + pic[h][w-1] + pic[h+1][w] + pic[h+1][w-1]);
            else if (h == height - 1 && w == width - 1)
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h-1][w] + 2 * pic[h][w-1] + 1 * pic[h-1][w-1])
                                /(pic[h][w] + pic[h-1][w] + pic[h][w-1] + pic[h-1][w-1]);
            else if (h == height - 1 && w == 0)
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h-1][w] + 2 * pic[h][w+1] + 1 * pic[h-1][w+1])
                /(pic[h][w] + pic[h-1][w] + pic[h][w+1] + pic[h-1][w+1]);
            else if (h == 0 && w == width - 1)
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w-1] + 2 * pic[h+1][w] + 1 * pic[h+1][w-1])
                /(pic[h][w] + pic[1][w-1] + pic[h+1][w] + pic[h+1][w-1]);
            else if (h == 0 && (w != 0 && w != width - 1))
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h-1][w] + 2 * pic[h][w+1]
                                + 1 * pic[h+1][w+1] + 1 * pic[h-1][w+1])/(pic[h][w] + pic[h+1][w] + pic[h-1][w]
                                + pic[h][w+1] + pic[h+1][w+1] + pic[h-1][w+1]);
            else if (w == 0 && (h != 0 && h != height - 1))
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h][w+1] + 2 * pic[h][w-1] + 1 * pic[h+1][w+1]
                                + 1 * pic[h+1][w-1])/(pic[h][w] + pic[h+1][w] + pic[h][w+1] + pic[h][w-1]
                                + pic[h+1][w+1] + pic[h+1][w-1]);
            else if (h == height - 1 && (w != 0 && w != width - 1))
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h-1][w] + 2 * pic[h][w-1] + 1 * pic[h+1][w-1]
                                + 1 * pic[h-1][w-1])/(pic[h][w] + pic[h+1][w] + pic[h-1][w] + pic[h][w-1]
                                + pic[h+1][w-1] + pic[h-1][w-1]);
            else if (w == width - 1 && (h != 0 && h != height - 1))
                newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1]
                                + 1 * pic[h-1][w-1])/(pic[h][w] + pic[h][w+1] + pic[h][w-1] + pic[h-1][w]
                                + pic[h-1][w+1] + pic[h-1][w-1]);
            else
                newPic[h][w] = (1 * pic[h-1][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1] + 2 * pic[h][w-1]
                                + 2 * pic[h][w] + 2 * pic[h][w+1] + 1 * pic[h+1][w-1] + 2 * pic[h+1][w] + 1
                                * pic[h+1][w+1]) / (pic[h][w] + pic[h-1][w-1] + pic[h-1][w] + pic[h-1][w+1]
                                + pic[h][w-1] + pic[h][w+1] + pic[h+1][w-1] + pic[h+1][w]);
        }
    }
    memcpy(pic, newPic, sizeof(newPic));
}

提供矩阵

10 100 10 100 10 100
10 100 10 100 10 100
100 10 100 10 100 10
100 10 100 10 100 10

“模糊”后的所需矩阵

48 46 64 46 64 61
55 48 61 48 61 55
55 61 48 61 48 55
61 64 46 64 46 48

“模糊”后的实际矩阵

2 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1


编辑:我更新了我的代码,以反映两个更正;所解决的第一个校正是第一个条件块中的[w-1]而不是[w + 1],并且所解决的第二个校正除以邻居密度的总和(而不是值的总和)。

Updated Code Block

if (h == 0 && w == 0)
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h+1][w] + 1 * pic[h+1][w+1])/7;
else if (h == height - 1 && w == width - 1)
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h-1][w] + 2 * pic[h][w-1] + 1 * pic[h-1][w-1])/7;
else if (h == height - 1 && w == 0)
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h-1][w] + 2 * pic[h][w+1] + 1 * pic[h-1][w+1])/7;
else if (h == 0 && w == width - 1)
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w-1] + 2 * pic[h+1][w] + 1 * pic[h+1][w-1])/7;
else if (h == 0 && (w != 0 && w != width - 1))
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h-1][w] + 2 * pic[h][w+1] + 1 * pic[h+1][w+1] + 1 * pic[h-1][w+1])/10;
else if (w == 0 && (h != 0 && h != height - 1))
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h][w+1] + 2 * pic[h][w-1] + 1 * pic[h+1][w+1] + 1 * pic[h+1][w-1])/10;
else if (h == height - 1 && (w != 0 && w != width - 1))
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h-1][w] + 2 * pic[h][w-1] + 1 * pic[h+1][w-1] + 1 * pic[h-1][w-1])/10;
else if (w == width - 1 && (h != 0 && h != height - 1))
  newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1] + 1 * pic[h-1][w-1])/10;
else
  newPic[h][w] = (1 * pic[h-1][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1] + 2 * pic[h][w-1] + 2 * pic[h][w] + 2 * pic[h][w+1] + 1 * pic[h+1][w-1] + 2 * pic[h+1][w] + 1 * pic[h+1][w+1]) / 14;

Updated Output

48  43  34  43  34  61
43  48  61  48  61  43
43  61  48  61  48  43
61  34  43  34  43  48

编辑2:事实证明我是一个大傻瓜,我的行和列在我脑海中翻转。以下工作正常,再次感谢大家的帮助!

Updated Code Block

// top left corner
if (h == 0 && w == 0)
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h+1][w] + 1 * pic[h+1][w+1])/7;
// bottom right corner
else if (h == height - 1 && w == width - 1)
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h-1][w] + 2 * pic[h][w-1] + 1 * pic[h-1][w-1])/7;
// top right corner
else if (h == height - 1 && w == 0)
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h-1][w] + 2 * pic[h][w+1] + 1 * pic[h-1][w+1])/7;
// bottom left corner
else if (h == 0 && w == width - 1)
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w-1] + 2 * pic[h+1][w] + 1 * pic[h+1][w-1])/7;
// top edges
else if (h == 0 && (w != 0 && w != width - 1))
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h][w-1] + 2 * pic[h+1][w]
                    + 1 * pic[h+1][w+1] + 1 * pic[h+1][w-1])/10;
// left edges
else if (w == 0 && (h != 0 && h != height - 1))
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h+1][w] + 2 * pic[h-1][w] + 1 * pic[h+1][w+1]
                    + 1 * pic[h-1][w+1])/10;
// bottom edges
else if (h == height - 1 && (w != 0 && w != width - 1))
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w+1] + 2 * pic[h][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1]
                    + 1 * pic[h-1][w-1])/10;
// right edges
else if (w == width - 1 && (h != 0 && h != height - 1))
    newPic[h][w] = (2 * pic[h][w] + 2 * pic[h+1][w] + 2 * pic[h-1][w] + 2 * pic[h][w-1] + 1 * pic[h+1][w-1]
                    + 1 * pic[h-1][w-1])/10;
// middle cells
else
    newPic[h][w] = (1 * pic[h-1][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1] + 2 * pic[h][w-1]
                    + 2 * pic[h][w] + 2 * pic[h][w+1] + 1 * pic[h+1][w-1] + 2 * pic[h+1][w] + 1
                    * pic[h+1][w+1]) / 14;

Updated Output

48  46  64  46  64  61
55  48  61  48  61  55
55  61  48  61  48  55
61  64  46  64  46  48
c++ image-processing matrix blur
2个回答
1
投票

您应该通过权重之和(而不是输入像素值的总和(或矩阵值,如果您愿意))对(除)进行归一化。

例如,第一种情况是:

newPic[h][w] = (2 * pic[h][w] + 2 * pic[h][w-1] + 2 * pic[h+1][w] + 1 * pic[h+1][w-1])
             / (2 + 2 + 2 + 1);

0
投票

你用一个太大的数字除以。对于一般情况,您应该除以14。

else
    newPic[h][w] = (1 * pic[h-1][w-1] + 2 * pic[h-1][w] + 1 * pic[h-1][w+1] + 2 * pic[h][w-1]
    + 2 * pic[h][w] + 2 * pic[h][w+1] + 1 * pic[h+1][w-1] + 2 * pic[h+1][w] + 1
    * pic[h+1][w+1]) / 14;

(这是因为14 = 1 + 2 + 1 + 2 + 2 + 2 + 1 + 2 + 1)

对于其他情况,除以该情况下系数的总和。

© www.soinside.com 2019 - 2024. All rights reserved.