c - 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 立方体:y
z
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 循环。例如,当a
example 为 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];
}
}
}
}
}
最后取 , 和 的平方变化之和x
的y
sqrt 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}}};
但我认为循环方法更性感。
解决方案
推荐阅读
- pandas - 使用 BeautifulSoup 抓取数据而不是获取所有行
- python - Django - 自动将对象 ID 的副本保存到第二个表
- asp.net-core - Vue中的axios授权请求失败
- python - 迭代生成器函数的问题
- linux - 确定优先级并杀死它们
- swift - Swift - 当应用程序移动到后台时调用 viewDidLoad
- javascript - 无法读取 HTML 和 JavaScript 中的 null 属性
- reactjs - 反应原生音频播放器
- node.js - Angular 9 - @angular/core/core"' 没有导出成员 'ɵɵFactoryDef'
- c - 将多个参数传递给一个选项时的 argv 的 getopt 顺序