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

时间:2019-03-28 23:43:25

标签: c++ image-processing matrix blur

问题

我正在尝试使用koef(如下所示)“模糊”矩阵(就像生成图像一样),但它没有达到我想要的方式。我通过.txt文件提供矩阵。

什么是koef?

This site在解释其工作原理方面做得很好。对于这种模糊,我使用“模糊光”,其koef为14,它是以下3x3矩阵(代表模糊密度)的总和:

1 2 1
2 2 2
1 2 1

可能有一种更简便的方法,而不是对同一件事进行9次硬编码。我也有手绘图来表示循环/条件结构,以及如果有用的话它们实际上在做什么。

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],而第二个校正是除以邻居的密度之和(而不是值的总和)。 / p>

更新的代码块

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;

更新后的输出

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

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

更新的代码块

// 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;

更新后的输出

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 个答案:

答案 0 :(得分: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);

答案 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)

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