Skip to content

Instantly share code, notes, and snippets.

@voidnerd
Last active August 25, 2022 12:13
Show Gist options
  • Save voidnerd/85e910bc6299022de95365948ef8f485 to your computer and use it in GitHub Desktop.
Save voidnerd/85e910bc6299022de95365948ef8f485 to your computer and use it in GitHub Desktop.
cs50 Problem Set 4 - Filter (less) Solution
#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;
}
@430lyj
Copy link

430lyj commented Feb 5, 2021

Hi, there! Probably you wrote this code few months ago (or maybe years ago), but i came across this code and get a lot of help! I just started programming and my code is never well-organized/designed. After seeing this code, makes me think more how the organized code works. Thanks :)

@voidnerd
Copy link
Author

voidnerd commented Feb 7, 2021

@430yj You are welcome.

@DButterflies
Copy link

Hi! Could you please explain this code? I am very new to coding and can code but I don't really understand the meaning behind the what? if you get what I mean...

@ayy99
Copy link

ayy99 commented Aug 12, 2021

i really couldnt understand line 67 , why did we put it this way {image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue}
why did we put that -1 ?

@ayy99
Copy link

ayy99 commented Aug 12, 2021

Hi! Could you please explain this code? I am very new to coding and can code but I don't really understand the meaning behind the what? if you get what I mean...

i only understood the first 2 functions so here is for the first function "(we declare an integer [height and width ] and then make a for loop tp loop over all of the rows for the height an width of the picture ,in the loop the initial value of i starts from 0 and get incremented as long as its less than the height , width of the picture ,then inside of this function we declared a float data type and called it [rgbtGray], which we will use to calculate the average of these three RGBTRIPLE which is just a struct that include data of (rgbtBlue-rgbtBlue-rgbtRed),then to limit the value that a pixel can have as we have a range of colors only from 0-255,we did make the function limit which is pretty much easily understood ,function 2(we declared an integer type of data for [sepiaBlue.sepiaRed,sepiaGreen ] cause they will be the outcome of the next calculation ,so we decclare them in advance to use them later ,then the next part happens to be the calculation part which doesnt really have much to do with , just copy paste it , but we did limited it so it doesnt exceed 255,then we set our output values to be equal to the new images height row and width row so its line 46-48

@Adham1302
Copy link

wow! your code is like mine but without the same comments

@michshliz
Copy link

hi! I tried to compile this code and run it just to see how it runs, but when i went to compile there appeared an error message saying it will not compile because it is not in a main function. I'm still new to coding and cant figure out how to compile it correctly without getting this error.

thanks!

@piter765
Copy link

in reflect function could you just swap pixels not colors in pixels?

@uka-amaka
Copy link

that's an amazing code you've got there

@aarushmanica
Copy link

hi! I tried to compile this code and run it just to see how it runs, but when i went to compile there appeared an error message saying it will not compile because it is not in a main function. I'm still new to coding and cant figure out how to compile it correctly without getting this error.

thanks!

Did you run ./filter -g images/yard.bmp out.bmp?

@ruiensim
Copy link

I feel that if change like this will be more productivity
int getBlur(int i, int j, int height, int width, RGBTRIPLE image[height][width], int number)
{
int sum = 0;
float counter = 0;
for (int k = i - 1; k < (i + 2); k++)
{

    for (int l = j - 1; l < (j + 2); l++)
    {
        

        if (k < 0 || k >= height )
        {
            
            break;
            
        }
        if (l < 0 || l >= width)
        {
            
            continue;
            
        }
        if (number == 0)
        {
            
            sum += image[k][l].rgbtRed;
            
            
        }
        else if (number == 1)
        {
            
            sum += image[k][l].rgbtGreen;
            
            
        }
        else 
        {
            
            sum += image[k][l].rgbtBlue;
            
            
        }
        counter++;
    }  
return round(sum / counter);

}

@shevchenko-oleks
Copy link

Thank you for posting it! May I ask why do you have to declare i and j in the int getBlur? can it be done inside with the float counter and int sum?

@shevchenko-oleks
Copy link

Also, would it be necessary to allocate (and free) memory for RGBTRIPLE copy image[height][width]? I guess the offered examples in cs50 are not that memory-consuming, but I just wonder at which point malloc and free would be needed (if at all needed).

@MrKubot
Copy link

MrKubot commented Oct 25, 2021

I don't understand... How it's possible, that these values from "void greyscale" are used for anything. It's void function and You aren't using any pointers. So these values should be lost after return;

@Mauricio7a
Copy link

Mauricio7a commented Nov 3, 2021

I don't understand... How it's possible, that these values from "void greyscale" are used for anything. It's void function and You aren't using any pointers. So these values should be lost after return;

Arrays are functionally the same as pointers, so they can be edited within functions. When you pass an Array into a function you're not passing a copy of each number in the array, you're passing a pointer to the data in the array. So even though the function doesn't return anything, it doesn't actually need to because the array is being edited directly from the function.

@Saifbabrak
Copy link

Can someone explain why we need to switch image[i][j] with image[i][width - j - 1] and not with image[i][width - j]?

@nathanik22
Copy link

@Saifbabrak I'll try, so my understanding is the pixel maps of these images for width and height start at 0 because it is an array. so position 0 is the first pixel. say we have an image that is 4 pixels wide, 4 pixels is our width, but the first pixel is going to be in position 0. so when J = 0 it is referring to the pixel in the leftmost position. that means the rightmost pixel in the 4 pixel wide image is in position 3. so if we just did [width - j], and j was 0 (the leftmost pixel), then our [width - j] will give us a value of [4], and since the pixel map for goes from left to right as [0] [1] [2] [3], then 4 is out of the array range.

can someone please tell me if I'm right? i am taking cs50 right now as a highschool senior but I am the biggest brick anyone has ever seen.

@LMNTLR
Copy link

LMNTLR commented Dec 12, 2021

Hey, thanks for this great code. I had multiple instances of going "Holy shit, that's so clever!".

Hope I'll be able to figure out such things on my own soon enough :D

@MariamYoussef23
Copy link

in the blur function, why do we have to make a copy of image? Can't we use image[i][j] right away?

@Fattu28
Copy link

Fattu28 commented Apr 17, 2022

i really couldnt understand line 67 , why did we put it this way {image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue} why did we put that -1 ?

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

@andujardani
Copy link

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

@dusty3d
Copy link

dusty3d commented Jun 16, 2022

liner-command

Help.

@josefine94
Copy link

josefine94 commented Jun 23, 2022

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;

`

@mmaszkiewicz8
Copy link

liner-command

Help.

i have the same problem. I don't know what I have to do with that. help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment