Disclaimer: These answers are only for educational purposes only. Please do not use them for cheating. Cheating doesn’t do any good for you!
In this post, I’m giving you my solutions to CS50 Problem Set 4 Filter (less comfortable / more comfortable) Problems and Recover problems. Hope these solutions will help you to better understand the problems and be a guide for your solutions too.
The Solution to CS50 Psets 4 Filter Problem – Less Comfortable (2022)
For this problem, we just have to implement a program that applies filters to BMPs. And a bunch of files were provided for us. We have to implement some functions in helpers.c to apply greyscale, Sepia, reflection, and blur filters to the given images.
The greyscale function turns the input image into a black-and-white version of it
// Convert image to grayscale void grayscale(int height, int width, RGBTRIPLE image[height][width]) { // Iterate through each column of pixel for (int i = 0; i < height; i++) { // Iterate through each raw of pixel in each column for (int j = 0; j < width; j++) { // Get into the 2D array, obtain value of each color int red = image[i][j].rgbtRed; int blue = image[i][j].rgbtBlue; int green = image[i][j].rgbtGreen; // Calculate the rounded avarage of each pixel int average = round(((float)red + (float)blue + (float)green) / 3); // Set the calculated value to be the new value of each pixel image[i][j].rgbtRed = image[i][j].rgbtBlue = image[i][j].rgbtGreen = average; } } }
The sepia function turns the input image into sepia version of the same image
// Convert image to sepia void sepia(int height, int width, RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int red = image[i][j].rgbtRed; int blue = image[i][j].rgbtBlue; int green = image[i][j].rgbtGreen; // New sapia values int sepiaRed = round(0.393 * red + 0.769 * green + 0.189 * blue); if (sepiaRed > 255) { image[i][j].rgbtRed = 255; } else { image[i][j].rgbtRed = sepiaRed; } int sepiaBlue = round(0.272 * red + 0.534 * green + 0.131 * blue); if (sepiaBlue > 255) { image[i][j].rgbtBlue = 255; } else { image[i][j].rgbtBlue = sepiaBlue; } int sepiaGreen = round(0.349 * red + 0.686 * green + 0.168 * blue); if (sepiaGreen > 255) { image[i][j].rgbtGreen = 255; } else { image[i][j].rgbtGreen = sepiaGreen; } } } }
The reflect function takes the image and reflects in horizontally
// Reflect image horizontally void reflect(int height, int width, RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { // Iterate through the array until you get the mid point for (int j = 0; j < (width / 2); j++) { RGBTRIPLE temp = image[i][j]; image[i][j] = image[i][width - (j + 1)]; image[i][width - (j + 1)] = temp; } } return; }
The blur function takes an image and turns it into a box-blurred version of the image
// Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { //create a temporary image to implement blurred algorithm on it. RGBTRIPLE temp[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int sumRed, sumBlue, sumGreen; sumRed = sumBlue = sumGreen = 0; float counter = 0.00; //Get the neighbouring pexels for (int c = -1; c < 2; c++) { for (int r = -1; r < 2; r++) { int currentX = i + c; int currentY = j + r; //check for valid neighbouring pexels if (currentX < 0 || currentX > (height - 1) || currentY < 0 || currentY > (width - 1)) { continue; } //Get the image value sumRed += image[currentX][currentY].rgbtRed; sumGreen += image[currentX][currentY].rgbtGreen; sumBlue += image[currentX][currentY].rgbtBlue; counter++; } //do the average of neigbhouring pexels temp[i][j].rgbtRed = round(sumRed / counter); temp[i][j].rgbtGreen = round(sumGreen / counter); temp[i][j].rgbtBlue = round(sumBlue / counter); } } } //copy the blurr image to the original image for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j].rgbtRed = temp[i][j].rgbtRed; image[i][j].rgbtGreen = temp[i][j].rgbtGreen; image[i][j].rgbtBlue = temp[i][j].rgbtBlue; } } return; }
Full code of helpers.c file
#include "helpers.h" #include <math.h> // Convert image to grayscale void grayscale(int height, int width, RGBTRIPLE image[height][width]) { // Iterate through each column of pixel for (int i = 0; i < height; i++) { // Iterate through each raw of pixel in each column for (int j = 0; j < width; j++) { // Get into the 2D array, obtain value of each color int red = image[i][j].rgbtRed; int blue = image[i][j].rgbtBlue; int green = image[i][j].rgbtGreen; // Calculate the rounded avarage of each pixel int average = round(((float)red + (float)blue + (float)green) / 3); // Set the calculated value to be the new value of each pixel image[i][j].rgbtRed = image[i][j].rgbtBlue = image[i][j].rgbtGreen = average; } } } // Convert image to sepia void sepia(int height, int width, RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int red = image[i][j].rgbtRed; int blue = image[i][j].rgbtBlue; int green = image[i][j].rgbtGreen; // New sapia values int sepiaRed = round(0.393 * red + 0.769 * green + 0.189 * blue); if (sepiaRed > 255) { image[i][j].rgbtRed = 255; } else { image[i][j].rgbtRed = sepiaRed; } int sepiaBlue = round(0.272 * red + 0.534 * green + 0.131 * blue); if (sepiaBlue > 255) { image[i][j].rgbtBlue = 255; } else { image[i][j].rgbtBlue = sepiaBlue; } int sepiaGreen = round(0.349 * red + 0.686 * green + 0.168 * blue); if (sepiaGreen > 255) { image[i][j].rgbtGreen = 255; } else { image[i][j].rgbtGreen = sepiaGreen; } } } } // Reflect image horizontally void reflect(int height, int width, RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { // Iterate through the array until you get the mid point for (int j = 0; j < (width / 2); j++) { RGBTRIPLE temp = image[i][j]; image[i][j] = image[i][width - (j + 1)]; image[i][width - (j + 1)] = temp; } } return; } // Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { //create a temporary image to implement blurred algorithm on it. RGBTRIPLE temp[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int sumRed, sumBlue, sumGreen; sumRed = sumBlue = sumGreen = 0; float counter = 0.00; //Get the neighbouring pexels for (int c = -1; c < 2; c++) { for (int r = -1; r < 2; r++) { int currentX = i + c; int currentY = j + r; //check for valid neighbouring pexels if (currentX < 0 || currentX > (height - 1) || currentY < 0 || currentY > (width - 1)) { continue; } //Get the image value sumRed += image[currentX][currentY].rgbtRed; sumGreen += image[currentX][currentY].rgbtGreen; sumBlue += image[currentX][currentY].rgbtBlue; counter++; } //do the average of neigbhouring pexels temp[i][j].rgbtRed = round(sumRed / counter); temp[i][j].rgbtGreen = round(sumGreen / counter); temp[i][j].rgbtBlue = round(sumBlue / counter); } } } //copy the blurr image to the original image for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j].rgbtRed = temp[i][j].rgbtRed; image[i][j].rgbtGreen = temp[i][j].rgbtGreen; image[i][j].rgbtBlue = temp[i][j].rgbtBlue; } } return; }
The Solution to CS50 Psets 4 Filter Problem – More Comfortable (2022)
For this problem also, we have to implement a program that applies filters to BMPs. And a bunch of files were provided for us. We have to implement some functions in helpers.c to apply greyscale, reflection, blur, and edge filters to the given images.
The greyscale function should take an image and turn it into a black-and-white version of the same image.
// Convert image to grayscale void grayscale(int height, int width, RGBTRIPLE image[height][width]) { // Iterate though each column for (int i = 0; i < height; i++) { // Iterate through each raw of pixel in each column for (int j = 0; j < width; j++) { // Get into 2D array and obtain value of each color int red = image[i][j].rgbtRed; int blue = image[i][j].rgbtBlue; int green = image[i][j].rgbtGreen; // Calculate the rounded avarage of each pixel int average = round(((float)red + (float)blue + (float)green) / 3); // Set the calculated value to be the new value of each pixel image[i][j].rgbtRed = image[i][j].rgbtBlue = image[i][j].rgbtGreen = average; } } return; }
The reflection function should take an image and reflect it horizontally
// Reflect image horizontally void reflect(int height, int width, RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { // Iterate through the array until you get the mid point for (int j = 0; j < (width / 2); j++) { RGBTRIPLE temp = image[i][j]; image[i][j] = image[i][width - (j + 1)]; image[i][width - (j + 1)] = temp; } } return; }
The blur function takes and image and turns it into a box-blurred version of the same image.
// Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { //create a temporary image to implement blurred algorithm on it. RGBTRIPLE temp[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int sumRed, sumBlue, sumGreen; sumRed = sumBlue = sumGreen = 0; float counter = 0.00; //Get the neighbouring pexels for (int c = -1; c < 2; c++) { for (int r = -1; r < 2; r++) { int currentX = i + c; int currentY = j + r; //check for valid neighbouring pexels if (currentX < 0 || currentX > (height - 1) || currentY < 0 || currentY > (width - 1)) { continue; } //Get the image value sumRed += image[currentX][currentY].rgbtRed; sumGreen += image[currentX][currentY].rgbtGreen; sumBlue += image[currentX][currentY].rgbtBlue; counter++; } //do the average of neigbhouring pexels temp[i][j].rgbtRed = round(sumRed / counter); temp[i][j].rgbtGreen = round(sumGreen / counter); temp[i][j].rgbtBlue = round(sumBlue / counter); } } } //copy the blurr image to the original image for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j].rgbtRed = temp[i][j].rgbtRed; image[i][j].rgbtGreen = temp[i][j].rgbtGreen; image[i][j].rgbtBlue = temp[i][j].rgbtBlue; } } return; }
The edges function takes an image and highlight the edges between objects, according to the sobel operator.
// Detect edges void edges(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE temp[height][width]; int gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; int gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float gxRed = 0; float gyRed = 0; float gxGreen = 0; float gyGreen = 0; float gxBlue = 0; float gyBlue = 0; for (int col = -1; col < 2; col++) { for (int row = -1; row < 2; row++) { if (i + col < 0 || i + col > height - 1) { continue; } if (j + row < 0 || j + row > width - 1) { continue; } gxRed += image[i + col][j + row].rgbtRed * gx[col + 1][row + 1]; gyRed += image[i + col][j + row].rgbtRed * gy[col + 1][row + 1]; gxGreen += image[i + col][j + row].rgbtGreen * gx[col + 1][row + 1]; gyGreen += image[i + col][j + row].rgbtGreen * gy[col + 1][row + 1]; gxBlue += image[i + col][j + row].rgbtBlue * gx[col + 1][row + 1]; gyBlue += image[i + col][j + row].rgbtBlue * gy[col + 1][row + 1]; } } int red = round(sqrt(gxRed * gxRed + gyRed * gyRed)); int green = round(sqrt(gxGreen * gxGreen + gyGreen * gyGreen)); int blue = round(sqrt(gxBlue * gxBlue + gyBlue * gyBlue)); // Cap at 255 if (red > 255) { red = 255; } if (green > 255) { green = 255; } if (blue > 255) { blue = 255; } // Assign new values to pixels temp[i][j].rgbtRed = red; temp[i][j].rgbtGreen = green; temp[i][j].rgbtBlue = blue; } } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j] = temp[i][j]; } } return; }
Full solution to cs50 psets 4 filter – more comfortable problem
#include "helpers.h" #include <math.h> // Convert image to grayscale void grayscale(int height, int width, RGBTRIPLE image[height][width]) { // Iterate though each column for (int i = 0; i < height; i++) { // Iterate through each raw of pixel in each column for (int j = 0; j < width; j++) { // Get into 2D array and obtain value of each color int red = image[i][j].rgbtRed; int blue = image[i][j].rgbtBlue; int green = image[i][j].rgbtGreen; // Calculate the rounded avarage of each pixel int average = round(((float)red + (float)blue + (float)green) / 3); // Set the calculated value to be the new value of each pixel image[i][j].rgbtRed = image[i][j].rgbtBlue = image[i][j].rgbtGreen = average; } } return; } // Reflect image horizontally void reflect(int height, int width, RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { // Iterate through the array until you get the mid point for (int j = 0; j < (width / 2); j++) { RGBTRIPLE temp = image[i][j]; image[i][j] = image[i][width - (j + 1)]; image[i][width - (j + 1)] = temp; } } return; } // Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { //create a temporary image to implement blurred algorithm on it. RGBTRIPLE temp[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int sumRed, sumBlue, sumGreen; sumRed = sumBlue = sumGreen = 0; float counter = 0.00; //Get the neighbouring pexels for (int c = -1; c < 2; c++) { for (int r = -1; r < 2; r++) { int currentX = i + c; int currentY = j + r; //check for valid neighbouring pexels if (currentX < 0 || currentX > (height - 1) || currentY < 0 || currentY > (width - 1)) { continue; } //Get the image value sumRed += image[currentX][currentY].rgbtRed; sumGreen += image[currentX][currentY].rgbtGreen; sumBlue += image[currentX][currentY].rgbtBlue; counter++; } //do the average of neigbhouring pexels temp[i][j].rgbtRed = round(sumRed / counter); temp[i][j].rgbtGreen = round(sumGreen / counter); temp[i][j].rgbtBlue = round(sumBlue / counter); } } } //copy the blurr image to the original image for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j].rgbtRed = temp[i][j].rgbtRed; image[i][j].rgbtGreen = temp[i][j].rgbtGreen; image[i][j].rgbtBlue = temp[i][j].rgbtBlue; } } return; } // Detect edges void edges(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE temp[height][width]; int gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; int gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { float gxRed = 0; float gyRed = 0; float gxGreen = 0; float gyGreen = 0; float gxBlue = 0; float gyBlue = 0; for (int col = -1; col < 2; col++) { for (int row = -1; row < 2; row++) { if (i + col < 0 || i + col > height - 1) { continue; } if (j + row < 0 || j + row > width - 1) { continue; } gxRed += image[i + col][j + row].rgbtRed * gx[col + 1][row + 1]; gyRed += image[i + col][j + row].rgbtRed * gy[col + 1][row + 1]; gxGreen += image[i + col][j + row].rgbtGreen * gx[col + 1][row + 1]; gyGreen += image[i + col][j + row].rgbtGreen * gy[col + 1][row + 1]; gxBlue += image[i + col][j + row].rgbtBlue * gx[col + 1][row + 1]; gyBlue += image[i + col][j + row].rgbtBlue * gy[col + 1][row + 1]; } } int red = round(sqrt(gxRed * gxRed + gyRed * gyRed)); int green = round(sqrt(gxGreen * gxGreen + gyGreen * gyGreen)); int blue = round(sqrt(gxBlue * gxBlue + gyBlue * gyBlue)); // Cap at 255 if (red > 255) { red = 255; } if (green > 255) { green = 255; } if (blue > 255) { blue = 255; } // Assign new values to pixels temp[i][j].rgbtRed = red; temp[i][j].rgbtGreen = green; temp[i][j].rgbtBlue = blue; } } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j] = temp[i][j]; } } return; }
The Solution to CS50 Psets 4 Recover Problem (2022)
For this problem, we have to implement a C program that will recover JPEG images from a forensic images. So we have to write our code in recover.c file. So here is my solution to this problem.
#include <stdio.h> #include <stdlib.h> #include <stdint.h> int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: ./recover card.raw\n"); return 1; } // Open file for read FILE *i = fopen(argv[1], "r"); //If fail to open input file retun error message "Could not open file" if (i == NULL) { printf("Could not open file"); return 2; } //declare a variable to unsigned char to store 512 chunks array unsigned char buffer[512]; //declare a variable to count image later in the loop int c = 0; //file pointer use to output data gotten from input file FILE *o = NULL; char *f = malloc(8 * sizeof(char)); // char file[8]; //Read 512 bytes from input file and store on the buffer while (fread(buffer, sizeof(char), 512, i)) { //check if bytes are from a JPEG if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) { //write jpeg inot file name in form 001.jpg, 002.jpg and so on sprintf(f, "%03i.jpg", c); //open output file for writing o = fopen(f, "w"); //count number of images found c++; } //Check if output have been used for valid input if (o != NULL) { fwrite(buffer, sizeof(char), 512, o); } } free(f); fclose(o); fclose(i); }
Hope these code solutions help you to solve your problems little bit easier. If it helps consider sharing with your friends that will need these solutions.