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;
}
@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