Could someone tell me where in my code I made a mistake? The values are failing check50. The loops seem to be correct, I really can't tell where the problem is.
I've looked at https://medium.com/swlh/cs50-pset-4-filter-8cbf734b0dbc and the code seems pretty much the same...
Thank you so much!
https://pastebin.com/MkZPFbEK
void edges(int height, int width, RGBTRIPLE image[height][width])
{
// for pixels at the border, treat value as B.G.R value as 0
// compute gx and gy for each value of B, G, R
// square root of gx and gy squared
RGBTRIPLE tempstore[height][width];
int Gx[3][3] = {
{-1, 0 , 1},
{-2, 0 , 2},
{-1, 0 , 1}
};
int Gy[3][3] = {
{-2, -1 , -1},
{0, 0 , 0},
{2, -1 , 1}
};
// for each row
for (int i = 0; i < height; i = i + 1)
{
// for each column
for (int j = 0; j < width; j = j + 1)
{
// float horvalueB=0;
// float horvalueG=0;
// float horvalueR=0;
// float vertvalueB=0;
// float vertvalueG=0;
// float vertvalueR=0;
float sumhorB=0;
float sumhorG=0;
float sumhorR=0;
float sumvertB=0;
float sumvertG=0;
float sumvertR=0;
// check if height of neighbor cell
for (int k = -1; k <= 1; k = k + 1)
{
for (int l = -1; l <= 1; l = l + 1)
{
int htcheck = i + k;
int wdcheck = j + l;
// check if height of neighbor cell is within bounds
if (((htcheck) >= 0) && ((htcheck) < height))
{
// check if width of neighbor cell is within bounds
if (((wdcheck) >= 0) && ((wdcheck) < width))
{
sumhorB += image[htcheck][wdcheck].rgbtBlue * Gx[k+1][l+1];
sumhorG += image[htcheck][wdcheck].rgbtGreen * Gx[k+1][l+1];
sumhorR += image[htcheck][wdcheck].rgbtRed * Gx[k+1][l+1];
sumvertB += image[htcheck][wdcheck].rgbtBlue * Gy[k+1][l+1];
sumvertG += image[htcheck][wdcheck].rgbtGreen * Gy[k+1][l+1];
sumvertR += image[htcheck][wdcheck].rgbtRed * Gy[k+1][l+1];
// sumhorB = sumhorB + horvalueB;
// sumhorG = sumhorG + horvalueG;
// sumhorR = sumhorR + horvalueR;
// sumvertB = sumvertB + vertvalueB;
// sumvertG = sumvertG + vertvalueG;
// sumvertR = sumvertR + vertvalueR;
}
}
}
}
int blue = round(sqrt( sumhorB*sumhorB + sumvertB*sumhorB ));
int green = round(sqrt( sumhorG*sumhorG + sumvertG*sumhorG ));
int red = round(sqrt( sumhorR*sumhorR + sumvertR*sumhorR ));
// Cap at 255
if (red > 255)
{
red = 255;
}
if (green > 255)
{
green = 255;
}
if (blue > 255)
{
blue = 255;
} // Assign new values to pixels
tempstore[i][j].rgbtRed = red;
tempstore[i][j].rgbtGreen = green;
tempstore[i][j].rgbtBlue = blue;
}
}
for (int i = 0; i < height; i = i + 1)
{
for (int j = 0; j < width; j = j + 1)
{
image[i][j].rgbtBlue = tempstore[i][j].rgbtBlue;
image[i][j].rgbtGreen = tempstore[i][j].rgbtGreen;
image[i][j].rgbtRed = tempstore[i][j].rgbtRed;
}
}
return;
}
Ahh.... The problem is I was multiplying the wrong things... Sorry about it. Was multiplying sumvert with sumhor...
int blue = round(sqrt( (sumhorB*sumhorB) + (sumvertB*sumhorB) ));
int green = round(sqrt( (sumhorG*sumhorG) + (sumvertG*sumhorG) ));
int red = round(sqrt( (sumhorR*sumhorR) + (sumvertR*sumhorR) ));
Should be
int blue = round(sqrt( (sumhorB*sumhorB) + (sumvertB*sumvertB) ));
int green = round(sqrt( (sumhorG*sumhorG) + (sumvertG*sumvertG) ));
int red = round(sqrt( (sumhorR*sumhorR) + (sumvertR*sumvertR) ));
Related
I'm trying to figure out what I did wrong. My intent is in title :)
This is the code I tried, and it clearly isn't working. It just print's 1 solid colour, also edges are not included yet. What part is wrong I can't figure it out what part of this code is wrong. It's just a function and it's in C.
void edges(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE edit[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
edit[i][j] = image[i][j];
}
}
for (int q = 1; q < height - 1; q++)
{
for (int w = 1; w < width - 1; w++)
{
int redEdit[9];
int greenEdit[9];
int blueEdit[9];
for (int top = 0; top < 3; top++)
{
redEdit[top] += edit[q - 1][w - 1 + top].rgbtRed;
greenEdit[top] += edit[q - 1][w - 1 + top].rgbtGreen;
blueEdit[top] += edit[q - 1][w - 1 + top].rgbtBlue;
}
int midctr = 0;
for (int mid = 3; mid < 6; mid++)
{
redEdit[mid] += edit[q][w - 1 + midctr].rgbtRed;
greenEdit[mid] += edit[q][w - 1 + midctr].rgbtGreen;
blueEdit[mid] += edit[q][w - 1 + midctr].rgbtBlue;
midctr ++;
}
int topctr = 0;
for (int top = 6; top < 9; top++)
{
redEdit[top] += edit[q + 1][w - 1 + topctr].rgbtRed;
greenEdit[top] += edit[q + 1][w - 1 + topctr].rgbtGreen;
blueEdit[top] += edit[q + 1][w - 1 + topctr].rgbtBlue;
topctr ++;
}
int matrixgx[] = {-1, 0, 1, -2, 0, 2, -1, 0, 1};
int matrixgy[] = {- 1, -2, -1, 0, 0, 0, 1, 2, 1};
int redEditgx[9];
int greenEditgx[9];
int blueEditgx[9];
int redEditgy[9];
int greenEditgy[9];
int blueEditgy[9];
for (int mtrx = 0; mtrx < 9; mtrx++)
{
redEditgx[mtrx] = redEdit[mtrx] * matrixgx[mtrx];
greenEditgx[mtrx] = greenEdit[mtrx] * matrixgx[mtrx];
blueEditgx[mtrx] = blueEdit[mtrx] * matrixgx[mtrx];
redEditgy[mtrx] = redEdit[mtrx] * matrixgy[mtrx];
greenEditgy[mtrx] = greenEdit[mtrx] * matrixgy[mtrx];
blueEditgy[mtrx] = blueEdit[mtrx] * matrixgy[mtrx];
}
// now sum up the changes of gx and gt
int redSumgx = 0;
int greenSumgx = 0;
int blueSumgx = 0;
int redSumgy = 0;
int greenSumgy = 0;
int blueSumgy = 0;
for (int sum = 0; sum < 9; sum++)
{
redSumgx += redEditgx[sum];
greenSumgx += greenEditgx[sum];
blueSumgx += blueEditgx[sum];
redSumgy += redEditgy[sum];
greenSumgy += greenEditgy[sum];
blueSumgy += blueEditgy[sum];
}
int finalRed = round(sqrt(pow(redSumgx, 2) + pow(redSumgy, 2)));
int finalGreen = round(sqrt(pow(greenSumgx, 2) + pow(greenSumgy, 2)));
int finalBlue = round(sqrt(pow(blueSumgx, 2) + pow(blueSumgy, 2)));
if (finalRed > 255)
{
finalRed = 255;
}
if (finalGreen > 255)
{
finalGreen = 255;
}
if (finalBlue > 255)
{
finalBlue = 255;
}
image[q][w].rgbtRed = finalRed;
image[q][w].rgbtGreen = finalGreen;
image[q][w].rgbtBlue = finalBlue;
}
}
return;
}
I know this code is cancer please don't judge
These arrays
int redEdit[9];
int greenEdit[9];
int blueEdit[9];
have not been initialised and hold arbitrary values. So when you execute statements such as
redEdit[top] += edit[q - 1][w - 1 + top].rgbtRed;
the sum is meaningless. You need
int redEdit[9] = { 0 };
int greenEdit[9] = { 0 };
int blueEdit[9] = { 0 };
Only static variables are implicitly initialised to 0. Local (auto) variables are not.
I am currently working on the blur function in PSET4 for filter-more, and I am struggling to find the bug in my code. The blur function seems to correctly filter the middle pixel and I would assume other pixels that are not on the edges, but is incorrectly filtering those on the corners and edges. Any nudges in the right direction would be greatly appreciated.
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// Copy to store filtered image into
RGBTRIPLE temp[height][width];
int red_total = 0, blue_total = 0, green_total = 0;
int red_average = 0, blue_average = 0, green_average = 0;
// Goes through each pixel [i][j]
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
// Loops through surrounding 3x3 grid and records the average of all of them
for (int h = -1; h < 2; h++)
{
// Checks if the current row is within the image array
if (i + h >= 0 && i + h < height)
{
for (int k = -1; k < 2; k++)
{
// Checks if current column is within image array
if (j + k >= 0 && j + k < width)
{
red_total = red_total + image[i + h][j + k].rgbtRed;
blue_total = blue_total + image[i + h][j + k].rgbtBlue;
green_total = green_total + image[i + h][j + k].rgbtGreen;
}
else continue;
}
}
else continue;
}
// Averages and reassigns pixel value
red_average = round(red_total / 9.0);
blue_average = round(blue_total / 9.0);
green_average = round(green_total / 9.0);
temp[i][j].rgbtBlue = blue_average;
temp[i][j].rgbtRed = red_average;
temp[i][j].rgbtGreen = green_average;
// Resets counter variables
red_total = green_total = blue_total = 0;
red_average = blue_average = green_average = 0;
}
}
// Makes image (original) array equal to the filtered image
for (int x = 0; x < height; x++)
{
for(int y = 0; y < width; y++)
{
image[x][y] = temp[x][y];
}
}
return;
}
So I've finished my edges function and I can't wrap my head around why it fails. Any help would be greatly appreciated! The edges function is supposed to detect edges in a bitmap.
Here is my edges function:
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
// Copy of image so that we calculate based on the original values of RGB
RGBTRIPLE copy[height][width];
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
copy[i][j] = image[i][j];
}
}
// Stores RGB values of each pixel in grid
RGBTRIPLE grid[3][3];
// Iterate over every pixel and alter its RGB values
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
reset(grid);
// Includes current pixel in center of 3 x 3 grid
grid[1][1] = copy[i][j];
// Checks if left edge exists and if so, assigns to left edge in 3 x 3 grid
if (j != 0)
{
grid[1][0] = copy[i][j - 1];
}
// Checks if right edge exists
if (j + 1 != width)
{
grid[1][2] = copy[i][j + 1];
}
// Checks if top edge exists
if (i != 0)
{
grid[0][1] = copy[i - 1][j];
}
// Checks if bottom edge exists
if (i + 1 != height)
{
grid[2][1] = copy[i + 1][j];
}
// Checks if top left corner exists
if (i != 0 && j != 0)
{
grid[0][0] = copy[i - 1][j - 1];
}
// Checks if top right corner exists
if (i != 0 && j + 1 != width)
{
grid[0][2] = copy[i - 1][j + 1];
}
// Checks if bottom left corner exists
if (i + 1 != height && j != 0)
{
grid[2][0] = copy[i + 1][j - 1];
}
// Checks if bottom right corner exists
if (i + 1 != height && j + 1 != width)
{
grid[2][2] = copy[i + 1][j + 1];
}
// Store products of x version and y version
RGBTRIPLE XX[3][3], YY[3][3];
duplicate(grid, XX);
duplicate(grid, YY);
// Multiplies each pixel in grid by corresponding values for x version
multiply(&XX[0][0], -1);
multiply(&XX[2][0], -1);
multiply(&XX[1][0], -2);
multiply(&XX[1][2], 2);
multiply(&XX[0][2], 1);
multiply(&XX[2][0], 1);
multiply(&XX[0][1], 0);
multiply(&XX[1][1], 0);
multiply(&XX[2][1], 0);
// Multiplies each pixel in grid by corresponding values for y version
multiply(&YY[0][0], -1);
multiply(&YY[0][2], -1);
multiply(&YY[0][1], -2);
multiply(&YY[2][1], 2);
multiply(&YY[2][0], 1);
multiply(&YY[2][2], 1);
multiply(&YY[1][0], 0);
multiply(&YY[1][1], 0);
multiply(&YY[1][2], 0);
// Stores sum of the products for x and y version
RGBTRIPLE Gx, Gy;
Gx.rgbtRed = Gx.rgbtGreen = Gx.rgbtBlue = Gy.rgbtRed = Gy.rgbtGreen = Gy.rgbtBlue = 0;
sum(&Gx, XX);
sum(&Gy, YY);
set_pixel(Gx, Gy, &image[i][j]);
}
}
}
Here are the functions that support edges:
// Sets new RGB values for a pixel
void set_pixel(RGBTRIPLE Gx, RGBTRIPLE Gy, RGBTRIPLE *pixel)
{
int red, green, blue;
red = (int) round(sqrt((Gx.rgbtRed * Gx.rgbtRed) + (Gy.rgbtRed * Gy.rgbtRed)));
green = (int) round(sqrt((Gx.rgbtGreen * Gx.rgbtGreen) + (Gy.rgbtGreen * Gy.rgbtGreen)));
blue = (int) round(sqrt((Gx.rgbtBlue * Gx.rgbtBlue) + (Gy.rgbtBlue * Gy.rgbtBlue)));
if (red > 255)
{
red = 255;
}
if (green > 255)
{
green = 255;
}
if (blue > 255)
{
blue = 255;
}
pixel->rgbtRed = red;
pixel->rgbtGreen = green;
pixel->rgbtBlue = blue;
}
// Adds the products for each colour together
void sum(RGBTRIPLE *sum, RGBTRIPLE g[3][3])
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
sum->rgbtRed += g[i][j].rgbtRed;
sum->rgbtGreen += g[i][j].rgbtGreen;
sum->rgbtBlue += g[i][j].rgbtBlue;
}
}
}
// Copies 3 x 3 grid into XX or YY
void duplicate(RGBTRIPLE grid[3][3], RGBTRIPLE c[3][3])
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
c[i][j] = grid[i][j];
}
}
}
// Resets 3 x 3 grid all to 0
void reset(RGBTRIPLE grid[3][3])
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
grid[i][j].rgbtRed = grid[i][j].rgbtGreen = grid[i][j].rgbtBlue = 0;
}
}
}
// Multiplies the amount of each colour by a given factor
void multiply(RGBTRIPLE *x, int factor)
{
x->rgbtRed *= factor;
x->rgbtGreen *= factor;
x->rgbtBlue *= factor;
}
For more info, here's what check50 says:
https://submit.cs50.io/check50/081a89d81042ad121b7f63d2af8deaf8225cca71
I doing filter of images bmp in c. The pset required the Sobel Operator. I don't know where I being mistake.
Help me please.
I'm basically making a copy of my image (because the original will be changed.)
Then I take the 3x3 values to put in the formula
So we add and multiply
Finally I take the result and put it in the formula: square root (Gx ^ 2 + Gy ^ 2)
If it exceeds 255 it must be 255, because RGB goes up to 255 which is white
And if there is a broken number, round to the nearest
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
// Variáveis
RGBTRIPLE temp[height][width];
int GR[3][3];
int GG[3][3];
int GB[3][3];
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}};
float resultR, resultG, resultB;
// Cópia temporária do original
for (int tempi = 0; tempi < height; tempi++)
{
for (int tempj = 0; tempj < width; tempj++)
{
temp[tempi][tempj].rgbtRed = image[tempi][tempj].rgbtRed;
temp[tempi][tempj].rgbtGreen = image[tempi][tempj].rgbtGreen;
temp[tempi][tempj].rgbtBlue = image[tempi][tempj].rgbtBlue;
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int countx = 0;
// Pegar 3X3
for (int x = i - 1; x < i + 2; x++)
{
int county = 0;
for (int y = j - 1; y < j + 2; y++)
{
if ((x < 0 || y < 0) || (x >= height || y >= width))
{
GR[countx][county] = 0;
GG[countx][county] = 0;
GB[countx][county] = 0;
}
else
{
GR[countx][county] = temp[x][y].rgbtRed;
GG[countx][county] = temp[x][y].rgbtGreen;
GB[countx][county] = temp[x][y].rgbtBlue;
}
county++;
}
countx++;
}
float sumxR = 0, sumyR = 0, sumxG = 0, sumyG = 0, sumxB = 0, sumyB = 0;
for (int ix = 0; ix <= 2; ix++)
{
for (int iy = 0; iy <= 2; iy++)
{
sumxR = sumxR + (GR[ix][iy] * Gx[ix][iy]);
sumxG = sumxG + (GG[ix][iy] * Gx[ix][iy]);
sumxB = sumxB + (GB[ix][iy] * Gx[ix][iy]);
sumyR = sumyR + (GR[ix][iy] * Gy[ix][iy]);
sumyG = sumyG + (GG[ix][iy] * Gy[ix][iy]);
sumyB = sumyB + (GB[ix][iy] * Gy[ix][iy]);
}
}
resultR = sqrt(sumxR * sumxR) + sqrt(sumyR * sumyR);
resultG = sqrt(sumxG * sumxG) + sqrt(sumyG * sumyG);
resultB = sqrt(sumxB * sumxB) + sqrt(sumyB * sumyB);
if (resultR > 255)
{
resultR = 255;
}
if (resultG > 255)
{
resultG = 255;
}
if (resultB > 255)
{
resultB = 255;
}
image[i][j].rgbtRed = round(resultR);
image[i][j].rgbtGreen = round(resultG);
image[i][j].rgbtBlue = round(resultB);
}
}
}
You need to changesqrt(sumxR * sumxR) + sqrt(sumyR * sumyR) to sqrt((sumxR * sumxR) + (sumyR * sumyR)) and they are not the same
I made a new post for the major changes in my post, but the problem now is that my image is returned as the same image entered. I believe it's a problem with the newimage variable and swapping it with the old image variable but I don't know why.
void edges(int height, int width, RGBTRIPLE image[height][width])
{
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}};
RGBTRIPLE newimage[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int redx = 0;
int greenx = 0;
int bluex = 0;
int redy = 0;
int greeny = 0;
int bluey = 0;
for (int k = i - 1; k <= i + 1 && k < height; k++)
{
for (int m = j - 1; m <= j + 1 && m < width; m++)
{
if (k != -1 && m != -1)
{
redx += image[k][m].rgbtRed * gx[k-(i-1)][m-(j-1)];
greenx += image[k][m].rgbtGreen * gx[k-(i-1)][m-(j-1)];
bluex += image[k][m].rgbtBlue * gx[k-(i-1)][m-(j-1)];
redy += image[k][m].rgbtRed * gy[k-(i-1)][m-(j-1)];
greeny += image[k][m].rgbtGreen * gy[k-(i-1)][m-(j-1)];
bluey += image[k][m].rgbtBlue * gy[k-(i-1)][m-(j-1)];
}
}
}
int finalred = round(sqrt((redx * redx) + (redy * redy)));
int finalgreen = round(sqrt((greenx * greenx) + (greeny * greeny)));
int finalblue = round(sqrt((bluex * bluex) + (bluey * bluey)));
if (finalred > 255)
{
finalred = 255;
}
if (finalgreen > 255)
{
finalgreen = 255;
}
if (finalblue > 255)
{
finalblue = 255;
}
newimage[i][j].rgbtRed = finalred;
newimage[i][j].rgbtGreen = finalgreen;
newimage[i][j].rgbtBlue = finalblue;
}
}
image = newimage;
return;
}