-
-
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! 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;
`
that's an amazing code you've got there