CS50:滤镜边缘 Returns 大部分为白色图像

CS50: Filter Edge Returns Mostly White Image

几天来我一直在使用 CS50 过滤器 - 边缘,很难确定我的代码有什么问题。此代码 returns 几乎都是白色图像(对我来说,这表明最终值对于每个像素来说都太大了)。任何帮助将不胜感激!

我也检查了我朋友的代码,我没有发现代码有任何明显的逻辑缺陷,图像大部分是白色的,图像中肯定没有检测到边缘。

void edges(int height, int width, RGBTRIPLE image[height][width])
{
    //Create Gx and Gy Matrixes
    int Gx[3][3]={{-1,0,1},{-2,0,2},{-1,0,1}};
    int Gy[3][3]={{-1,-2,-1},{0,0,0},{1,2,1}};
    //create copy of image
    RGBTRIPLE copy[height][width];
    for(int row=0; row<height;row++)
    {
        for(int col=0; col<width; col++)
        {

            copy[row][col].rgbtBlue=image[row][col].rgbtBlue;
            copy[row][col].rgbtRed=image[row][col].rgbtRed;
            copy[row][col].rgbtGreen=image[row][col].rgbtGreen;
        }
    }
    //create loop for edge detection
    int red; int blue; int green;
    double Gxsum[3]; double Gysum[3]; double finalval[3];
    int icount; int jcount;

    for(int row=0; row<height; row++)//inside image loop
    {

        for(int col=0; col<width; col++)
        {
            Gxsum[0]=0.0; Gxsum[1]=0.0; Gxsum[2]=0.0;
            Gysum[0]=0.0; Gysum[1]=0.0; Gysum[2]=0.0;
            icount=0; jcount=0;
            for(int i=row-1; i<=row+1; i++)//inside 3x3 loop
            {
                for(int j=col-1; j<=col+1; j++)
                {
                    if(i<0||j<0||i>=height||j>=width)
                    {
                        red=0.0;blue=0.0;green=0.0;
                    }
                    else
                    {
                    red=copy[i][j].rgbtRed;
                    blue=copy[i][j].rgbtBlue;
                    green=copy[i][j].rgbtGreen;
                    Gxsum[0]+=Gx[icount][jcount]*red;
                     Gxsum[1]+=Gx[icount][jcount]*blue;
                     Gxsum[2]+=Gx[icount][jcount]*green;
                     Gysum[0]+=Gy[icount][jcount]*red;
                     Gysum[1]+=Gy[icount][jcount]*blue;
                     Gysum[2]+=Gy[icount][jcount]*green;
                    }

                     jcount++;
                }
                icount++;
            }
            finalval[0]=round(sqrt(Gxsum[0]*Gxsum[0] + Gysum[0]*Gysum[0]));//red
            finalval[1]=round(sqrt(Gxsum[1]*Gxsum[1] + Gysum[1]*Gysum[1]));//blue
            finalval[2]=round(sqrt(Gxsum[2]*Gxsum[2] + Gysum[2]*Gysum[2]));//green

            for(int k=0; k<3; k++)
            {
                if (finalval[k]>255)
                {
                    finalval[k]=255;
                }

            }

//now assign image pixel to newvals;

image[row][col].rgbtRed=(int)finalval[0];
image[row][col].rgbtBlue=(int)finalval[1];
image[row][col].rgbtGreen=(int)finalval[2];

        }
    }
    return;
}

我认为您的代码包含编译错误和运行时错误。当您执行时,您只是 运行 版本来自课程 material。因此结果是白色图像。

首先,您需要#include <math.h>才能使用sqrt()round()。其次,有一个逻辑错误,您忘记在每行完成后将 jcount 重置为 0。当 jcount 变为 3 时,数组索引越界。

以下是我更正后的简化版本

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    //Create Gx and Gy Matrixes
    int gx[3][3] = { {-1,0,1},{-2,0,2},{-1,0,1} };
    int gy[3][3] = { {-1,-2,-1},{0,0,0},{1,2,1} };
    // max of each channel
    const int channelCap = 255;
    //create copy of image
    RGBTRIPLE copy[height][width];
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {

            copy[row][col].rgbtBlue = image[row][col].rgbtBlue;
            copy[row][col].rgbtRed = image[row][col].rgbtRed;
            copy[row][col].rgbtGreen = image[row][col].rgbtGreen;
        }
    }
    //create loop for edge detection
    int red; int blue; int green;
    double finalRed, finalGreen, finalBlue;
    double gxRed, gxGreen, gxBlue;
    double gyRed, gyGreen, gyBlue;

    for (int row = 0; row < height; row++)//inside image loop
    {

        for (int col = 0; col < width; col++)
        {
            gxRed = 0.0; gxGreen = 0.0; gxBlue = 0.0;
            gyRed = 0.0; gyGreen = 0.0; gyBlue = 0.0;
            int icount = 0, jcount = 0;

            for (int i = row - 1; i <= row + 1; i++)//inside 3x3 loop
            {
                for (int j = col - 1; j <= col + 1; j++)
                {
                    if (i >= 0 && j >= 0 && i < height && j < width)
                    {
                        // within boundary
                        red = copy[i][j].rgbtRed;
                        blue = copy[i][j].rgbtBlue;
                        green = copy[i][j].rgbtGreen;

                        gxRed += gx[icount][jcount] * red;
                        gxBlue += gx[icount][jcount] * blue;
                        gxGreen += gx[icount][jcount] * green;
                        gyRed += gy[icount][jcount] * red;
                        gyBlue += gy[icount][jcount] * blue;
                        gyGreen += gy[icount][jcount] * green;
                    }
                    jcount++;

                }
                icount++;
                jcount = 0;
            }

            finalRed = fmin(round(sqrt(gxRed * gxRed + gyRed * gyRed)), channelCap);//red
            finalBlue = fmin(round(sqrt(gxBlue * gxBlue + gyBlue * gyBlue)), channelCap);//blue
            finalGreen = fmin(round(sqrt(gxGreen * gxGreen + gyGreen * gyGreen)), channelCap);//green

            //now assign image pixel to newvals;
            image[row][col].rgbtRed = (int)finalRed;
            image[row][col].rgbtBlue = (int)finalBlue;
            image[row][col].rgbtGreen = (int)finalGreen;

        }
    }
    return;
}

$ ./filter -e ./images/yard.bmp outfile.bmp

结果: