Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 实现Sobel过滤器时会产生奇怪的结果_C_Image Processing - Fatal编程技术网

C 实现Sobel过滤器时会产生奇怪的结果

C 实现Sobel过滤器时会产生奇怪的结果,c,image-processing,C,Image Processing,我一直在学习计算机视觉,想用C语言实现一些简单的技术。对于第一种技术,我正在做Sobel边缘检测滤波器。我理解它是如何工作的,所以我认为编写代码应该相当容易,但我得到了非常奇怪的结果 我使用的是下图: 结果呢 新结果!: 应该注意的是,我使用的是.ppm图像格式(链接指向jpgs,因为我找不到支持.ppm的图像主机) 无论如何,下面是我实现Sobel的代码部分: /********************************************************** This

我一直在学习计算机视觉,想用C语言实现一些简单的技术。对于第一种技术,我正在做Sobel边缘检测滤波器。我理解它是如何工作的,所以我认为编写代码应该相当容易,但我得到了非常奇怪的结果

我使用的是下图:

结果呢

新结果!:

应该注意的是,我使用的是.ppm图像格式(链接指向jpgs,因为我找不到支持.ppm的图像主机)

无论如何,下面是我实现Sobel的代码部分:

/**********************************************************
This program takes in an image file and applies the Sobel
Filter edge detection technique to it.
**********************************************************/

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

void sobelFilter(){


    //Sobel kernels dx (horizontal) and dy (vertical)
    int horizFilter[3][3] = {{ 1,   0,  -1},
                             { 2,   0,  -2},
                             { 1,   0,  -1}};
    int vertFilter[3][3]  = {{ 1,   2,   1},
                             { 0,   0,   0},
                             {-1,  -2,  -1}};
    int pixVal = 0; 
    int horizPixVal = 0;
    int vertPixVal = 0;
    int x, y, i, j;

    //Quick check to make sure dimensions are correct
    printf("Using a Width of: %d\n", width);
    printf("Using a Height of: %d\n\n", height);

    //Start filtering process here
    for(x = 0; x < width; x++){
        for(y = 0; y < height; y++){
            pixVal = 0;
            horizPixVal = 0;
            vertPixVal = 0;
            if(!((x == 0) || (x == width-1) || (y == 0) || (y == height-1))){           //If the current pixel is along the border, ignore it and set to zero
                for(i = -1; i <= 1; i++){                                               //because the kernel does not align to it
                    for(j = -1; j <= 1; j++){
                        horizPixVal += (int)(image[y + j][x + i][0]) * horizFilter[i + 1][j + 1];       //Only need to focus on one of the RGB values since the output is
                        vertPixVal  += (int)(image[y + j][x + i][0]) * vertFilter[i + 1][j + 1];        //greyscale and all three values are the same
                    }
                }
            }
            pixVal = sqrt((horizPixVal * horizPixVal) + (vertPixVal * vertPixVal));     //Calculate magnitude
            pixVal = sqrt(horizPixVal * horizPixVal);
            if(pixVal > 255) pixVal = 255;                                              //Clamp value within 8-bit range
            filteredImage[y][x][0] = (unsigned char)pixVal;                             
        }
    }
}
/**********************************************************
该程序接收图像文件并应用Sobel
滤波边缘检测技术。
**********************************************************/
#包括
#包括
#包括
#包括“ppmReader.h”
void sobelFilter(){
//Sobel内核dx(水平)和dy(垂直)
int horizFilter[3][3]={{1,0,-1},
{ 2,   0,  -2},
{ 1,   0,  -1}};
int vertFilter[3][3]={{1,2,1},
{ 0,   0,   0},
{-1,  -2,  -1}};
int-pixVal=0;
int horizPixVal=0;
int vertPixVal=0;
int x,y,i,j;
//快速检查以确保尺寸正确
printf(“使用的宽度为:%d\n”,宽度);
printf(“使用高度:%d\n\n”,高度);
//在这里开始过滤过程
对于(x=0;x对于(i=-1;i图像通常首先以
y
坐标索引,然后以
x
坐标索引,如下所示:

... image[y + j][x + i] ...
这是一个惯例,让人们在处理C语言中的图像时不会感到困惑。不幸的是,它与Matlab使用的有点矛盾,所以我只希望您在C语言中完成这一切

此外,表示红色/绿色/蓝色值是交错的,因此“颜色平面”必须是最后一个索引:

... image[y + j][x + i][0] ...
除非在将输入文件加载到内存时对其进行了一些重新排序。您没有显示从该文件读取的代码,因此很难知道它是否进行了任何重新排序


添加:读取和写入文件应遵循光栅顺序,即在继续下一行之前完成一行的像素:

for(y = 0; y < height; y++){
    for(x = 0; x < width; x++){
        ...
    }
}
(y=0;y{ 对于(x=0;x

还建议以这种方式进行处理;这不是绝对必须的,但它将减少混乱,并可能使处理速度更快(通过更有效地使用CPU缓存)。

您应该使用一些更小、更简单的测试映像(例如,所有“1”或单独的“1”)对此进行调试.我看不出该代码中有任何明显的问题(当然不会给出您看到的输出),尽管存在一些较小的问题(例如,您不应该对图像使用指针数组;而应该使用单个1D数组来提高速度)。你的问题几乎可以肯定是与之前或之后的代码有关,尽管你相信。@Dave-我同意1D数组,并计划在我修复了该问题后这样做,以使代码更干净。我从其他人的示例开始使用3d数组,但我被这个问题缠住了,决定可以使用草率的数组退一步。很高兴你能证实我的想法,没有明显的问题,计算似乎是正确的。@奥利-我将尝试更小的图像,以便获得调试所需的原始数据点,谢谢。你是否为
image
filteredImage
设置/分配了内存?你能显示这部分代码吗?不,我没有.ppm reader/writer函数中的任何重新排序,因此我继续将索引调整为[y][x][color]您指定的格式,它提供了更好的结果!我没有完全填充框中的白色,而是正确地检测边缘!这很好,但图像仍然是上图中的三倍重叠。我本来打算发布所有三个函数,但我认为一个问题发布的代码可能太多。Shou我能把所有的都贴出来吗?你也许能自己弄明白。请尝试,如果你失败了,请描述你的尝试;如果你需要阅读和写作功能的帮助,请贴出来。是的,我会尝试看看我能找到什么,我花了好几个小时在Sobel函数上,什么也没找到。现在你已经告诉我了索引作为一个问题,我要走这条路,感觉更有希望。谢谢!我只是想回来说声谢谢!你的建议奏效了,在我发布上述评论并再次查看你的帖子后,我很快就发现了我索引中的错误。这是我最后一次说我100%确定问题没有发生这个或那个。(老实说,作为一名计算机“科学家”,我应该早就知道了!我感到羞愧哈哈)
... image[y + j][x + i][0] ...
for(y = 0; y < height; y++){
    for(x = 0; x < width; x++){
        ...
    }
}