100% Guaranteed Results


SER334 – Solved
$ 24.99
Category:

Description

5/5 – (1 vote)

Image Processing
Summary: In this homework, you will be implementing a program that loads an image le, applies ltering to it, and saves it back to disk. You will also learn how to read and write real-world binary le
formats, speci cally BMP.
1 Background
In this assignment you will write a program that applies three di erent lters to an image. The image will be loaded from a BMP le, speci ed by the user, and then be transformed using: 1) a grayscale conversion, 2) a color shift also speci ed by the user, or 3) a scale operation. The resulting le will be saved back to a BMP le that can be viewed on the system.
This document is separated into four sections: Background, Requirements, Loading Binary Files, Include Files, and Submission. You have almost nished reading the Background section already. In Requirements, we will discuss what is expected of you in this homework. In Loading Binary Files, we will discuss the BMP le format and how to interact with binary les. Lastly, Submission discusses how your source code should
be submitted on Canvas.
2 Requirements [36 points]
As a base requirement, your program must compile and run under Xubuntu (or another variant of Ubuntu) 20.04. Several sample outputs are shown in subsection 2.1. Do not modify the header les given except to ll in any TODOs.
Speci c Requirements:
BMP Headers IO: Create structures for the headers of a BMP le (BMP header struct and DIB header struct) and functions which read and write them. [4 Points]
* See struct BMP_Header, struct DIB_Header, readBMPHeader, writeBMPHeader, readDIBHeader, writeDIBHeader, makeBMPHeader, and makeDIBHeader. These functions should be implemented in a le called BMPHandler.c.
Pixel IO: Create a structure which represents a single pixel (24-bit pixel struct) and the functions for reading and writing all pixels in BMP les. [4 Point]
* See struct Pixel, readPixelsBMP, and writePixelsBMP. These functions should be implemented in a le called BMPHandler.c.
Input and output le names: Read the input le name and output le name from the command line arguments. The user should be required to enter the input le name and this should be the rst argument. The output le name is an option, it is not required and it can be in any place in the option list. The output le option is speci ed by -o followed by the output le name. Validate that the input le exists. [4 Points]
* The input le is the le to read and copy.
* The output le name is the le to write to and copy to (the new le created).
Filter command line parsing: Accept an option for grayscale (black and white). This is speci ed by “-w”. Accept options for red, green, or blue color shift. These are speci ed by -r -g or -b followed by an integer. Accept an option for scale. This is speci ed by “-s” followed by a oat. Like the -o option described above, these can come in any order in the option list and are optional for the user to enter. [4 Points]
Copy images: Have the ability to copy an image from a BMP le to a new BMP le. [4 Points]
Grayscale lter (image_apply_bw): convert each RGB pixel to its grayscale equivalent. [4
Points]
* In a grayscale image, each RGB component has the same value. Use the following formula to compute it: grayscale = 0.299R + 0.587G + 0.114B
* This lter MUST happen before the color shift lter is applied.
Color Shift lter (image_apply_colorshift): Shift the color of the new image before saving it, according to the options the user entered. [4 Points]
* Color shift refers to increasing or decreasing the color in a pixel by the speci ed amount. So, if the user entered -b -98 all of the blue values in a pixel would be decreased by 98.
* If no color shift option was entered for a color, do not shift it.
* After color shift, color should be clamped to 0 ~ 255. For example, color R = 100, shift = 200. The color R after shift should be 255 (300 clamped to 255).
Scaling lter (image_apply_resize): perform nearest neighbor resize on the image. [4 Points]
* Create a new pixel array of the appropriate size (e.g., old_width * scaling_factor).
* For each pixel in the new pixel array, set it’s value to (roughly) the nearest neighbor in the original. For example, if you have an image that is 100×100 and being resized to 50×50, then the pixel at 25×25 in the smaller resized image would be same as the one at 50×50 in the original. (Informally, the pixel half way through a smaller image would be the same as the image halfway through the larger image.
OOP: Follow the provided header le for Image to structure it as an object. The Image functions ( ve below and three lters above) should be implemented in a le called Image.c. [4 Points]
* See image_create, image_destroy, image_get_pixels, image_get_width, image_get_height.
2.1 Sample Outputs
ImageProcessor ttt.bmp -r 56

Output le name was ttt_copy.bmp.
ImageProcessor ttt.bmp -r 56 -b 78 -g 45 -o ltered1.bmp

ImageProcessor ttt.bmp -w -r 56 -b 78 -g 45 -o ltered2.bmp

ImageProcessor ttt.bmp -w -o ltered3.bmp

ImageProcessor ttt.bmp -s 2.0 -o ltered4.bmp

ImageProcessor ttt.bmp -s 2.0 -w -o ltered5.bmp

ImageProcessor ttt.bmp -w -s .5 -r 56 -o ltered6.bmp

3 Loading Binary Files
3.1 The BMP File Format
For reference, use the BMP speci cation on Wikipedia: https://en.wikipedia.org/wiki/BMP_ le_format. In Figure 1, a graphical overview of a BMP le’s layout is shown. The layout is literally the meaning of the bits/bytes in the le starting at 0 and going to the end of the le. The rst (green) region shows the BMP header information in 14 bytes: 2 for the signature, 4 for the le size, 2 for reserved1, 2 for reserved2, and 4 for le o set. Details on each of these (such as their data format, and contents) can be found on the Wikipedia page. For example, the area labeled Signature should contain the characters BM to con rm that the le is in BMP format. The second (blue region) shows the DIP header information in 40 bytes: 4 for header size, 4 for width, 4 for height, and so on. The last region (yellow) forms a 2D array of pixels. It stores columns from left to right, but rows are inverted to be bottom to top. Note that each row of pixels in this section is padded to be a multiple of four bytes. For example, if a line contains two pixels (24-bits or 3-bytes each), then an addition 2-bytes of blank data will be appended.
Review the following struct called BMP_Header which holds the bmp header information. (You should also consider creating structs to hold the dib header, and pixel data.) Notice that the entries in BMP_Header correspond to the pieces of data listed in the le format. In general, a chunk of 8-bits should be represented as a char, a chunk of 16-bits as a short, and 32-bits as a int. (Optionally: consider using unsigned types.) struct BMP_Header { char signature [ 2 ] ; //ID f i e l d
int size ; // Size of the BMP f i l e short reserved1 ; // Application s p e c i f i c short reserved2 ; // Application s p e c i f i c
int offset_pixel_array ; // Offset where the pixel array can be found
};
Plan to review Example 1 on the Wikipedia page to get a feel for the contents of each of these regions. A recreated version of that image is provided as the attached test2.bmp le. A good exercise would be to view the le in a hex editor like Bless.

Figure 1: BMP le format structure for 24-bit les without compression. Image modi ed from https://en.wikipedia.org/wiki/File:BMP leFormat.png.
3.2 Loading the BMP header
This is example of code to load the BMP le header (the rst 14 bits). Figure 2 shows the output.

Figure 2: Output of base le on test2.bmp.
//sample code to read f i r s t 14 bytes of BMP f i l e format
FILE* f i l e = fopen (” test2 .bmp” , “rb “); struct BMP_Header header ;
//read bitmap f i l e header (14 bytes ) fread(&header . signature , sizeof ( char )*2 , 1 , f i l e ); fread(&header . size , sizeof ( int ) , 1 , f i l e ); fread(&header . reserved1 , sizeof ( short ) , 1 , f i l e ); fread(&header . reserved2 , sizeof ( short ) , 1 , f i l e ); fread(&header . offset_pixel_array , sizeof ( int ) , 1 , f i l e );
printf (” signature : %c%c ” , header . signature [0] , header . signature [ 1 ] ) ; printf (” size : %d ” , header . size ); printf (” reserved1 : %d ” , header . reserved1 ); printf (” reserved2 : %d ” , header . reserved2 );
printf (” offset_pixel_array : %d ” , header . offset_pixel_array );
fclose ( f i l e ); The key functions here are:
FILE *fopen ( const char *filename , const char *mode)
This creates a new le stream. fopen is used with the rb mode to indicate we are r eading a le in b inary mode. To read a le, use the mode wb instead of rb .
size_t fread ( void *ptr , size_t size , size_t nitems , FILE *stream )
For each call to fread, we give it rst a pointer to an element of struct containing the BMP header, then the number of bytes to read, the number of times to read (typically 1), and the le stream to use. Note that order of the calls to fread de ne the order in which we read data so the order must match the le layout. (There is also a function called fwrite which works in exactly the opposite manner. The rst parameter won’t be a pointer though.)
int fseek ( FILE * stream , long int offset , int origin )
The purpose of fseek is to move the reading head of the FILE object by some number of bytes. It can used to skip a number of bytes. The rst parameter to fseek is the le pointer, followed by a number of bytes to move, and an origin. For origin, SEEK_CUR is a relative repositioning while SEEK_SET is global repositioning.
The basic idea to support loading a BMP le will be to parse it by byte-byte (using fread) into a set of structs. Later, you can use fwrite to write out the contents of those structs to a le stream to save the ltered image.
3.3 Making BMP le headers
When creating a new BMP, especially one that has been resized, you will need to ll in the header of the new le yourself. For example, you will need to ll in the compression type, the number of color planes, etc for BMP les. The following de nes default values you should use when creating an image. All values that are not de ned here, you should calculate based on the input image.
BMP Header:
Signature: BM Reserved 1: 0
Reserved 2: 0 DIB Header:
Planes: 1
Compression: 0
Horizontal resolution: 3780
Vertical resolution: 3780
Color number: 0
Important color number: 0
4 Include Files
stdio.h: De nes standard IO functions. stdlib.h: De nes memory allocation functions.
string.h: De nes string manipulation functions.
char* strcat(char* dest, const char* src): The strcat() function appends the string pointed to by src to the end of the string pointed to by dest.
char* strcpy(char* dest, const char* src): The strcpy() function copies the string pointed to, by src to dest.
size_t strlen(const char* str): The strlen() function computes the length of the string str up to, but not including the terminating null character.
char* strtok_r(char* str, const char* delim, char** saveptr): The strtok_r function parses a string into a sequence of tokens.
unistd.h: De nes POSIX operating system API functions.
int getopt(int argc, char *const argv[], const char *optstring): The getopt() function is a builtin function in C and is used to parse command line arguments.
5 Submission
The submission for this assignment has one part: a source code submission. The les should be zipped in a le named “LastNameImageProcessor.zip” (e.g. “EdgarImageProcessor.zip”) attached to the homework submission link on Canvas.
Writeup: For this assignment, no write up is required.
Source Code: Please name your main le as “LastNameImageProcessor.c” (e.g. “EdgarImageProcessor.c”). Your ZIP should also include: BMPHandler.c, BMPHandler.h, Image.c, and Image.h.

Reviews

There are no reviews yet.

Be the first to review “SER334 – Solved”

Your email address will not be published. Required fields are marked *

Related products