Date: Spring 2015
This assignment is the creation of a basic image proccessing program. It is like a mini photoshop or photo editor
Please note that all images on this website are converted to .jpg from the .bmp output of the program.
command line arguments: ./image -brightness [factor] < in.bmp > out.bmp Brightness is controlled by scaling the pixels by the inputed factor. The factor must be non-negative. 1.0 preserves the image, 0.0 makes it black, and other factors scale up the pixel values.
command line arguments: ./image -contrast [factor] < in.bmp > out.bmp Contrast is controlled by interpolating the pixels between a gray image of the average image luminance and the original image. A factor of 0.0 outputs the calculated constant gray image, 1.0 gives the original image, and negative values inverts the image. Values between 0.0 and 1.0 have less contrast, and values greater than 1.0 has higher contrast.
command line arguments: ./image -saturation [factor] < in.bmp > out.bmp Saturation is controlled by interpolating the pixels between a gray-scale version of the original image and the original image. The grayscale image is constructed form the pixel luminance. Negative values inverts the image hue but keeps the luminance. A factor of 0.0 outputs the calculated greyscale image, 1.0 preserves the original image, and negative values invert the colors. Values between 0.0 and 1.0 make the image more gray, and values greater than 1.0 are extrapolated to increase the saturation.
command line arguments: ./image -gamma [factor] < in.bmp > out.bmp Gamma correction adjusts the color of each pixel of the image by the factor. The factor must be a postitive number. A factor of 1.0 preserves the original image, values greater than 1 brighten the image, and values less than 1 darken it.
command line arguments: ./image -crop [x] [y] [w] [h] < in.bmp > out.bmp Cropping is done by selecting a rectangular section of the image at the given starting point up to the size specified. x and y are the point to begin cropping from, and w and h are the size of the output cropped image. The x value must be in the range 0 to width-1(left to right) and y must be in the range 0 to height -1 (top to bottom). All parameters must be postive.
For all of the Quantization and Dithering methods the number of bits must be between 1 and 8.
command line arguments: ./image -quantize [bits] < in.bmp > out.bmp For each color channel in the image I first convert the value to a floating point number p between 0 and 1, then use q = floor(p * b), where b = 2^bits. I then convert back to the 0-255 range using color = floor(255*q/(b-1)).
command line arguments: ./image -randomDither [bits] < in.bmp > out.bmp I then added an option to add random noise to the quantizing function. THe noise ranges from -0.5 to 0.5, and is added using q = floor(p*b + noise).
command line arguments: ./image -FloydSteinbergDither [bits] < in.bmp > out.bmp In this algorithm the error made during quantizing is diffused to other pixels later on using the given weights:
Right = 7/16, bottomleft = 3/16, bottom = 5/16, bottomright = 1/16.
For all functions needing special cases for the edges, I initally used image wrapping. I achieved this by using a helper function to calculate a modified index if necessary.
The helper function int wrapImg (int max, int idx) takes the maximum value an index can be and the current index, and returns a modified index if the current index is less than 0 or greater than or equal to the max. As you can see with the wave image this may not be ideal, since the top of the image is very light and the bottom of the image is very dark.
To deal with this, I decided to use the reflection method instead. The helper function int reflectImg (int max, int idx), which reflects out of bounds points back into the image.
When I implemented edge detection, the helper function int reflectImg (int max, int idx), created some errors on the border which I did not like. To deal with this, I switched to a new helper function int validImg (int max, int idx) which instead only uses valid pixels in the image.
command line arguments: ./image -blur [width] < in.bmp > out.bmp The blur kernel width parameter must be an odd integer. A gaussian filter with the given width is used for discrete convolution with the image. I set sigma = floor(n/2.0)/2.0 as given in the assignment.
command line arguments: ./image -sharpen < in.bmp > out.bmp I used the filter provided in the assignment writeup.
command line arguments: ./image -edgeDetect [threshold] < in.bmp > out.bmp Edge detection using sobel filters
command line arguments: ./image -sampling [type] -size [w] [h] < in.bmp > out.bmp Nearest Neighbor:
Hat Filter: f(x) = 1 - |x|
Mitchell Filter:
f(0 <= |x| < 1) = (1/6)*(7|x|^3 - 12|x|^2 + 6/3)
f(1 <= |x| < 2) = (1/6)*((-7/3)|x|^3 + 12|x|^2 - 20|x| + 32/3)
command line arguments: ./image -shift [sx] [sy] < in.bmp >out.bmp Nearest Neighbor:
Hat Filter: f(x) = 1 - |x|
Mitchell Filter:
f(0 <= |x| < 1) = (1/6)*(7|x|^3 - 12|x|^2 + 6/3)
f(1 <= |x| < 2) = (1/6)*((-7/3)|x|^3 + 12|x|^2 - 20|x| + 32/3)
command line arguments: ./image -fun < in.bmp >out.bmp I decided to implement a swirl effect. I use the mitchell filter for anti-aliasing. I searched for math equations for the swirl effect online and found several different ones. All of these left black pixels where there were no image pixels to sample, but I instead used my sampling method which uses the wrapping method. The function I chose to use to transform the pixels is newX = x*cos(angle) - y*sin(angle) +xcenter and newY = x*sin(angle) + y*cos(angle) + ycenter and r = (x*x + y*y) where angle is a function of r.