c - Sobel Operator C - 边缘检测出错

标签 c binary 2d gradient edge-detection

我一直在努力使用 Sobel 运算符在 C 中计算二值图像的梯度(和倾角)。我已经多次检查过运营商并浏览了大量的互联网站点。尽管如此,我不得不承认我没有图像处理方面的经验,而且我在 C 编码方面是一个菜鸟。我没有收到任何错误消息,但结果并未在边缘显示所需的渐变。 以某种方式未计算 x 方向上的梯度 - 但为什么呢?

感谢您的帮助!

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

FILE *infile, *outfile;


int main(int argc, char *argv[])
{
    int nx,nz,k,i,nu;
    int j,m,l;
    int km, kp, im, ip, kpp, ipp;
    float Gx, Gz, G, Gmax, Gmin;
    float T;
    float **dip;
    float pi;
    float *tmp;                                      
    float *bufz;                                      
    float **temp1;

    char *velfile_in = "vel";//"vel_315_273";
    char *velfile_out = "dip";


    void *alloc1 (size_t n1, size_t size);            
    void **alloc2(size_t n1, size_t n2, size_t size); 
    void ***alloc3(size_t n1, size_t n2, size_t n3, size_t size);


    pi = 4. * atan(1.);

    // Initiate constants
    T = atof(argv[1]);
    nx = atoi(argv[2]);
    nz = atoi(argv[3]);

    Gmax = 0.;
    Gmin = 10e8;

    // border handling (cyclic) 
    km = (k+nz-1) % nz;
    kp = (k+1) % nz;
    kpp = (k+2) % nz;
    im = (i+nx-1) % nx;
    ip = (i+1) % nx;
    ipp = (i+2) % nx;


    // allocate 1D, 2D and 3D arrays
    tmp = (float *)alloc1(nz,sizeof(float));
    bufz = (float *)alloc1(nz,sizeof(float));
    temp1 = (float **)alloc2(nx,nz,sizeof(float));
    dip = (float **)alloc2(nx,nz,sizeof(float));


    //READ FILE
    //***********************************************************
    infile = fopen(velfile_in, "r");
    if (infile == NULL) err("Error: could not open file.");
    for (i=0; i<nx; i++) {
        nu = fread(tmp,sizeof(float),nz,infile);
        for (k=0; k<nz; k++) {
            temp1[k][i] = tmp[k];
        }
    }
    fclose(infile);


    // APPLY SOBEL****************************************

    for (i = 0; i < nx; i++)
    {
        for (k = 0; k < nz; k++)
        {

            Gx = (temp1[km][im] - temp1[km][ip] + 2 * temp1[k][im] - 2 * temp1[k][ip] + temp1[kp][im] - temp1[kp][ip]); 
            Gz = (temp1[km][im] - temp1[kp][im] + 2 * temp1[km][i] - 2 * temp1[kp][i] + temp1[km][ip] - temp1[kp][ip]); 


            G = sqrtf(Gx * Gx + Gz * Gz);
            Gmax =  (Gmax > G ? Gmax : G);
            Gmin =  (Gmin < G ? Gmin : G);  

            dip[k][i] = abs(atan(Gz/Gx) * 180. / pi);

            printf("(%d,%d)\tGx:%5.3f\tGz%5.3f\tG%5.3f\n",i,k,Gx,Gz,G);

        }
    }

    printf("Gmax:%5.3f\tGmin:%5.3f\n",Gmax,Gmin);



    // write file ********************************************************
    outfile = fopen(velfile_out,"w");
    for (i=0; i<nx; i++) {
        for (k=0; k<nz; k++) bufz[k] = dip[k][i];
        fwrite(bufz,sizeof(float),nz,outfile);
    }

    fclose(outfile);

    return 0;
}

Input Image Result of Dip

最佳答案

明显的问题是您的卷积核没有移动 - 数组索引都是单独的变量,需要更新以与 ij 保持同步。在循环内移动赋值应该可以解决这个问题:

...
for (i = 0; i < nx; i++)
{
    im = (i+nx-1) % nx;
    ip = (i+1) % nx;
    ipp = (i+2) % nx;

    for (k = 0; k < nz; k++)
    {
        km = (k+nz-1) % nz;
        kp = (k+1) % nz;
        kpp = (k+2) % nz;
...

关于c - Sobel Operator C - 边缘检测出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21055472/

相关文章:

javascript - 从二进制 "01000111"中获取所有索引值为 1

javascript - 简单的动态二维数组问题

c# - XNA C# 可破坏地形

java - 同时选择两个或多个形状

c - C 中参数的顺序

c - Centos中如何限制进程可以使用的最大内存?

c++ - FFMPEG Seeking 带来音频伪像

java - 在 Java 中将二进制实数转换为 double - 例如,0.011011110010101 到 .4342

binary - Erlang 二进制分割

c - while 循环的错误输出