Jackson Kruger
Initial work for this went smoothly - cmake made compilation very simple and straightforward. This took a very long time overall,
and many mistakes were made along the way. They're detailed in the rightmost column.
Some of the effects aren't obvious due to the size the images are displayed at, so if something doesn't seem right, open the image in a new tab
or save & open the image. Additionally, all of the input and output images are available
here and here,
respectively.
Source code is on Github. image.cpp
A compiled executable for Ubuntu can be found here: Image.out
Feature | Argument(s) | Input Image | Output Image | Comments | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Brighten | -brightness 1.5 |
|
||||||||
Random Noise | -noise 0.5 |
|
||||||||
Crop | -crop 50 50 200 300 | |||||||||
Extract Channel | -extractChannel 1 | |||||||||
Contrast | -contrast 0.1 |
|
I had a great deal of trouble implementing contrast, as I initially thinking about it completely wrong. I was calculating the average luminance of the whole picture, then calculating the difference between that and each pixel's luminance. I then multiplied that difference by the contrast factor, and added it to the average luminance. I considered green and blue as function of red. I then did some algebraic manipulation to calculate the red value necessary to get the desired luminance, and calculated green and blue from that red. This method produced some very interesting results, shown below. |
|||||||
Saturation | -saturation 0.1 |
|
||||||||
Quantize | -quantize 1 |
|
I first implemented quantization incorrectly, scaling as if the passed value was the max color value, not the number of bits.
It was a pretty simple adjustment to my math to operate correctly (just calculate maxValue as 2^n - 1).
|
|||||||
Random Dither | -randomDither 1 |
|
||||||||
Floyd-Steinberg dither | -FloydSteinbergDither 1 |
|
I got some very poor results when I had accidentally flipped the order of subtraction for calculating error, but discovered my mistake quickly. |
|||||||
Blur | -blur 2 |
|
I implemented a Gaussian convolution for this, and it's performed separably. The filter is scaled by the number inputted. |
|||||||
Sharpen | -sharpen 2 |
|
Implementing sharpening after implementing blur was trivial. |
|||||||
Edge Detect | -edgeDetect |
I used a modified sobel filter for my edge detection. I also reduce saturation to 0 before processing, and added 1 level of blur.
My implementation uses the sobel filters plus two complementary filters to detect edges it wouldn't otherwise. (If I remember correctly,
before I added these it only detected bottom and left edges).
|
||||||||
Scale | -scale 10 10 |
|
Note that these are all css-scaled to be the same size, though the output images are actually 10 times as big as the input in each direction. The input image is actually only 45x34 pixels. The images can be saved or opened in separate tabs to see this. |
|||||||
-scale 0.25 0.25 |
|
These illustrate the special case of reducing size by a power of two for point sampling and bilinear sampling.
|
||||||||
Rotate | -rotate 45 |
|
I had a lot of trouble with off-by-one style errors near the edges when rotating by a factor of 90 deg. I had to do a bit of a hack to fix it.
|
|||||||
Fun | -fun | |||||||||
"Purplifier" |
|
These were some fun mistake outputs while I was working on contrast. It was basically reinterpreting the image in terms of the luminance function, with some interpolation. The code is at the bottom of image.cpp in a method called "Purplify". |
||||||||
Another fun mistake |