首页 > 解决方案 > C语言中的3D 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++) {

我创建了一个数组,它将容纳、 和方向的变化x,并循环通过一个 3x3x3 立方体:yz

    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。

内核像素的符号将仅由 、 或 的a符号b确定c

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

现在我遍历a, b, 并将c它们打包成一个数组并从 0-1-2 循环。例如,当aexample 为 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];
                    }
                }
            }
        }
    }

最后取 , 和 的平方变化之和xysqrt z

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

但我认为循环方法更性感。

标签: cimage-processing3dedge-detectionsobel

解决方案


推荐阅读