Last active
August 25, 2022 12:13
-
-
Save voidnerd/85e910bc6299022de95365948ef8f485 to your computer and use it in GitHub Desktop.
cs50 Problem Set 4 - Filter (less) Solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "helpers.h" | |
#include <math.h> | |
// Convert image to grayscale | |
void grayscale(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
float rgbGray; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) { | |
rgbGray = round( (image[i][j].rgbtBlue + image[i][j].rgbtGreen + image[i][j].rgbtRed)/ 3.00); | |
image[i][j].rgbtBlue = rgbGray; | |
image[i][j].rgbtGreen = rgbGray; | |
image[i][j].rgbtRed = rgbGray; | |
} | |
} | |
return; | |
} | |
int limit(int RGB) | |
{ | |
if (RGB > 255) | |
{ | |
RGB = 255; | |
} | |
return RGB; | |
} | |
// Convert image to sepia | |
void sepia(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
int sepiaBlue; | |
int sepiaRed; | |
int sepiaGreen; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
sepiaBlue = limit(round(0.272 * image[i][j].rgbtRed + 0.534 * image[i][j].rgbtGreen + 0.131 * image[i][j].rgbtBlue)); | |
sepiaGreen = limit(round(0.349 * image[i][j].rgbtRed + 0.686 * image[i][j].rgbtGreen + 0.168 * image[i][j].rgbtBlue)); | |
sepiaRed = limit(round(0.393 * image[i][j].rgbtRed + 0.769 * image[i][j].rgbtGreen + 0.189 * image[i][j].rgbtBlue)); | |
image[i][j].rgbtBlue = sepiaBlue; | |
image[i][j].rgbtGreen = sepiaGreen; | |
image[i][j].rgbtRed = sepiaRed; | |
} | |
} | |
return; | |
} | |
// Reflect image horizontally | |
void reflect(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
int temp[3]; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width / 2; j++) { | |
/** Swap pixels from left to right */ | |
temp[0] = image[i][j].rgbtBlue; | |
temp[1] = image[i][j].rgbtGreen; | |
temp[2] = image[i][j].rgbtRed; | |
image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue; | |
image[i][j].rgbtGreen = image[i][width - j - 1].rgbtGreen; | |
image[i][j].rgbtRed = image[i][width - j - 1].rgbtRed; | |
image[i][width - j - 1].rgbtBlue = temp[0]; | |
image[i][width - j - 1].rgbtGreen = temp[1]; | |
image[i][width - j - 1].rgbtRed = temp[2]; | |
} | |
} | |
return; | |
} | |
int getBlur(int i, int j, int height, int width, RGBTRIPLE image[height][width] , int color_position) | |
{ | |
float counter = 0; | |
int sum = 0; | |
/** Start from 1 row before it and end at 1 row after it- total of 3rows */ | |
for (int k = i - 1; k < (i + 2); k++) | |
{ | |
/** Start from 1 block before it and end at 1 block after it- total of 3blocks */ | |
for (int l = j - 1; l < (j + 2); l ++) | |
{ | |
if(k < 0 || l < 0 || k >= height || l >= width) | |
{ | |
continue; | |
} | |
if (color_position == 0) | |
{ | |
sum += image[k][l].rgbtRed; | |
} | |
else if (color_position == 1) | |
{ | |
sum += image[k][l].rgbtGreen; | |
} | |
else | |
{ | |
sum += image[k][l].rgbtBlue; | |
} | |
counter++; | |
} | |
} | |
return round(sum /counter); | |
} | |
// Blur image | |
void blur(int height, int width, RGBTRIPLE image[height][width]) | |
{ | |
RGBTRIPLE copy[height][width]; | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
copy[i][j] = image[i][j]; | |
} | |
} | |
for (int i = 0; i < height; i++) | |
{ | |
for (int j = 0; j < width; j++) | |
{ | |
image[i][j].rgbtRed = getBlur(i, j, height, width, copy, 0); | |
image[i][j].rgbtGreen = getBlur(i, j, height, width, copy, 1); | |
image[i][j].rgbtBlue = getBlur(i, j, height, width, copy, 2); | |
} | |
} | |
return; | |
} |
in the blur function, why do we have to make a copy of image? Can't we use image[i][j] right away?
You need a copy of the image because you will be modifying the pixels of the original one in each loop. If you don't work with a copy you would be calculating the average of blue (for example) with pixels that are already the average of the surrounding pixels
You can make the reflect even more compact by using the defined RGBTruple. Since we dont alter the RGB I tried to find a way just to save the pixel value, thought it was bool first but checked the bmp.h
`
RGBTRIPLE tValue = image[i][j];
image[i][j] = image[i][width - j - 1];
image[i][width - j - 1] = tValue;
`
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I know this was like an year ago but , as you may recall in the lectures, it was mentioned that in a loop starting at 0. the last column will be width - 1. so to access the last column, we put a -1