C语言中的3D Sobel运算符算法

时间:2018-10-25 01:45:31

标签: c image-processing 3d edge-detection sobel

我目前正在努力用C制作3D Sobel边缘检测器(我还很陌生)。它不能完全按预期工作(突出显示实体3D对象中的非边缘),我希望有人可以看到我出了问题的地方。 (对不起,这篇文章中的空格不多)

首先,im是已复制到tm的输入图像,每边的边界均为1像素。

我遍历图像:

for (z = im.zlo; z <= im.zhi; z++) {
    for (y = im.ylo; y <= im.yhi; y++) {
        for (x = im.xlo; x <= im.xhi; x++) {

我制作了一个数组,该数组将容纳xyz方向的更改,并循环通过3x3x3立方体:

    int dxdydz[3] = {0, 0, 0};
    for (a = -1; a < 2; a++) {
        for (b = -1; b < 2; b++) {
            for (c = -1; c < 2; c++) {

现在是这里的肉,有点棘手。我正在对我的Sobel运算符进行加权,以便如果您想象内核的一个2D表面,则该表面将是{{1,2,1},{2,4,2},{1,2,1}}。换句话说,核心像素的权重与其到中心像素的4连通度有关。

为此,我将e定义为3-(| a | + | b | + | c |),以使其为0、1或2。内核将按3加权。每个像素处的^ e。

内核像素的符号将仅由abc的符号确定。

                int e = 3 - (abs(a) + abs(b) + abs(c));

现在,我通过将abc打包成一个数组并从0-1-2循环来遍历。例如,当a为0时,我们不想向x添加任何值,因此我们使用if语句(深度为8级!)来排除该值。

                int abc[3] = {a, b, c};
                for (i = 0; i < 3; i++) {
                    if (abc[i] != 0) {

要添加的值应仅为该像素处的图像值乘以该像素处的内核值。 abc[i]仅为-1或1,而(int)pow(3, e)是接近中心的权重。

                        dxdydz[i] += abc[i]*(int)pow(3, e)*tm.u[z+a][y+b][x+c];
                    }
                }
            }
        }
    }

最后获取xyz中平方变化之和的平方根。

    int mag2 = 0;
    for (i = 0; i < 3; i++) {
    mag2 += (int)pow(dxdydz[i], 2);
    }
        im.u[z][y][x] = (int)sqrt(mag2);
    }
}
}

当然,我可以遍历图像并将3x3x3立方体乘以3D内核:

int kx[3][3][3] = {{{-1,-2,-1},{0,0,0},{1,2,1}},
  {{-2,-4,-2},{0,0,0},{2,4,2}},
  {{-1,-2,-1},{0,0,0},{1,2,1}}}; 
int ky[3][3][3] = {{{-1,-2,-1},{-2,-4,-2},{-1,-2,-1}},
      {{0,0,0},{0,0,0},{0,0,0}},
      {{1,2,1},{2,4,2},{1,2,1}}}; 
int kz[3][3][3] = {{{-1,0,1},{-2,0,2},{-1,0,1}},
      {{-2,0,2},{-4,0,4},{-2,0,2}},
      {{-1,0,1},{-1,0,1},{-1,0,1}}};

但是我认为循环方法要性感得多。

0 个答案:

没有答案