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
结果:
几天来我一直在使用 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
结果: