我已經在 CS50 Filter - 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}};
//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;
}
uj5u.com熱心網友回復:
我認為您的代碼包含編譯錯誤和運行時錯誤。當您執行時,您只是在運行來自課程材料的版本。因此,結果是白色影像。
首先,您需要#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
結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/472827.html
