-
-
Save voidnerd/85e910bc6299022de95365948ef8f485 to your computer and use it in GitHub Desktop.
#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; | |
} |
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 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 ?
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
wow! your code is like mine but without the same comments
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!
in reflect function could you just swap pixels not colors in pixels?
that's an amazing code you've got there
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?
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);
}
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?
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).
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;
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.
Can someone explain why we need to switch image[i][j] with image[i][width - j - 1] and not with image[i][width - j]?
@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.
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
in the blur function, why do we have to make a copy of image? Can't we use image[i][j] right away?
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
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;
`
@430yj You are welcome.