CS50 Week 4 Problem Set: Filter-less
Hello newbie coders! My name is Kevin and this blog is my documentation of my coding journey which I started 4 weeks ago.
I am currently in Week 4: Memory of the CS50x course, and the practice problems, labs, and problem sets in this week really felt like there was quite a leap in difficulty level.
For the problem set "Filter", this one really had me stumped for two days. In the end, I figured out that my calculations for the averages were giving wrong numbers because I was not dividing by a FLOAT variable.
The function that I found particularly challenging was the blur function. So if you're stuck and don't want to look up the answer yet, here are some tips that may help you out:
The blur function will require 4 "for" loops. Two to iterate through all the pixels, and two to iterate through the surrounding pixels of the pixel you will blur.
Use FLOAT variables when making divisions.
If you still have difficulty figuring it out, I have pasted my own code below, which passes check50 100%. Just keep in mind that copy-pasting the code into this blog made some of the indentations weird. Also, keep in mind that I'm a beginner and some of my code may not be the best way to do it.
Good luck with the Week 4 problem sets, and don't give up! :)
<code>
#include "helpers.h"
#include <math.h>
#include <stdio.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
int average; // The average of red, green, and blue values
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
// Calculate average
average = round((image[i][j].rgbtRed + image[i][j].rgbtGreen +
image[i][j].rgbtBlue) / 3.0);
// Assign average to all colors
image[i][j].rgbtRed = average;
image[i][j].rgbtGreen = average;
image[i][j].rgbtBlue = average;
}
}
return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
// Temporary placeholders for colors used to facilitate calculation of sepia
int orig_red, orig_green, orig_blue;
// Temporary placeholders for new colors (in case they are over 255)
int new_red, new_green, new_blue;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
orig_red = image[i][j].rgbtRed;
orig_green = image[i][j].rgbtGreen;
orig_blue = image[i][j].rgbtBlue;
new_red = round(.393 * orig_red + .769 * orig_green + .189 * orig_blue);
new_green = round(.349 * orig_red + .686 * orig_green + .168 * orig_blue);
new_blue = round(.272 * orig_red + .534 * orig_green + .131 * orig_blue);
// This will cap the red to 255
if (new_red > 255)
{
image[i][j].rgbtRed = 255;
}
else
image[i][j].rgbtRed = new_red;
// This will cap the green to 255
if (new_green > 255)
{
image[i][j].rgbtGreen = 255;
}
else
image[i][j].rgbtGreen = new_green;
// This will cap the blue to 255
if (new_blue > 255)
{
image[i][j].rgbtBlue = 255;
}
else
image[i][j].rgbtBlue = new_blue;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
// These temporary matrices will be used to store a copy of the image
int temp_red[height][width], temp_green[height][width], temp_blue[height][width];
// Let's the populate the temporary matrices here
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp_red[i][j] = image[i][j].rgbtRed;
temp_green[i][j] = image[i][j].rgbtGreen;
temp_blue[i][j] = image[i][j].rgbtBlue;
}
}
// Now we can flip the image by assigning the color values
// at the end of a row to the beginning of the row
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtRed = temp_red[i][width - 1 - j];
image[i][j].rgbtGreen = temp_green[i][width - 1 - j];
image[i][j].rgbtBlue = temp_blue[i][width - 1 - j];
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// this will create a copy of image
RGBTRIPLE temp[height][width];
// make a copy of image[height][width]
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp[i][j] = image[i][j];
}
}
// use "for" loop to iterate through 'i' values of 'image'
for (int i = 0; i < height; i++)
{
// use "for" loop to iterate through 'j' values 'image'
for (int j = 0; j < width; j++)
{
// total values of surrounding colors for every pixel, before taking average
// total values of surrounding colors for every pixel, before taking average
int total_red = 0, total_green = 0,
total_blue = 0;
// counts number of valid pixels
float total_pixels = 0.00;
// use 2 "for" loops again to iterate through surrounding pixels
for (int x = -1; x < 2; x++)
{
for (int y = -1; y < 2; y++)
{
int i_counter = i + x;
int j_counter = j + y;
// this 'if' statement will filter out any invalid pixles
if (i_counter < 0 || j_counter < 0 ||
i_counter > height - 1 || j_counter > width - 1)
{
continue;
}
// ELSE increment color RGB values
else
{
total_red += temp[i_counter][j_counter].rgbtRed;
total_green += temp[i_counter][j_counter].rgbtGreen;
total_blue += temp[i_counter][j_counter].rgbtBlue;
total_pixels++;
}
}
}
// get averages and update image[i][j] color values
image[i][j].rgbtRed = round(total_red / total_pixels);
image[i][j].rgbtGreen = round(total_green / total_pixels);
image[i][j].rgbtBlue = round(total_blue / total_pixels);
}
}
return;
}
</code>
Subscribe to my newsletter
Read articles from Kevin Hindriks directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Kevin Hindriks
Kevin Hindriks
I am a full-time filmmaker, learning how to code to add to my skillset.