please don't kill me for deeply nested for loops and neglecting to factor out methods
To execute scripts:
node scriptrunner.js
Computes the discrete Fourier transform of 1-D list of complex numbers in file in.
usage: dft: in dir out
in: [FILE] 1-D list of complex numbers.
dir: [INT] 0 or 1.
out: [FILE] 1-D list of complex numbers. stored as 2 columns in file: real, imaginary. The first line of the file consists of 2 numbers: width & height
####convolve.cpp
Convolve input image in with kernel and store result in out. Convolution kernel is stored in file kernel.
kernel is a 2-D array of ASCII numbers. first line of this file consists of width & height.
-
Read kernel ASCII values from file in.
-
Pad the input image using pixel replication.
-
Apply the Kernel filter to the input image.
-
profit.
usage: convolve: in kernel out
in: [FILE] input file. PGM Format.
kernel: [FILE] input kernel. File consisting of ASCII numbers.
out: [FILE] output file. PGM Format.
####median.cpp
Apply median filter to in over a neighborhood of size sz * sz. Input values are sorted and the median is averaged with avg_nbrs pixels below and avg_nbrs pixels above the sorted list. result is stored in out. If avg_nbrs = 0, then output is the median. If avg_nbrs = sz^2 / 2, then the output should be idential to blur.cpp pad image using pixel replication.
-
pad the input image using pixel replication technique.
-
create circular buffer that conforms to kernel size.
-
using the circular buffer, apply median technique where the sz * sz kernel is sorted and the median value is taken.
usage: median in sz avg_nbrs out
in: [FILE] input file. PGM format.
sz: [INT] Median filter kernel size of sz * sz. Odd.
avg_nmbrs: [INT] integer value representing the pixels to the left and right of the current pixel that will be averaged with the median of median kernel. Cannot be larger than sz.
out: [FILE] output file. PGM format.
####sharpen.cpp
Sharpen an image by subtracting a blurred version from it's original value and the scaled difference back to input image.
usage: sharpen in sz fctr out
in: [FILE] input image. PGM file.
sz: [INT] filter of dimension sz * sz.
fctr: [INT] A multiplier that will be applied to the difference between blurred and original image.
out: [FILE] output image.
####blur.cpp
usage: blur in xsz ysz out
in: infile.
xsz: number of columns used in box filter
ysz: number of rows used in box filter.
out: outfile.
Reads an input image in and blurs it with a box filter, kernel using unweighted averaging. Kernel filter has dimensions xsz * ysz where xsz is are rows and ysz are columns. xsz and ysz must be odd.
-
blur the rows, store in temporary buffer.
-
then pass do a pass on the temporary buffer and blur the columns.
-
store the result in output image.
####error_diffusion.cpp
usage: error_diffusion infile mtd serpentine gamma outfile
mtd: 0; Use Floyd Steinberg Error Diffusion Algorithm.
mtd: 1; Use Jarvis-Judice-Ninke Error Diffusion Algorithm.
gamma: use 1.0 for no gamma correction.
serpentine: 1; Use serpentine scanning method, where even rows are processed left to right while odd rows are processed right to left.
serpentine: 0; scan left to right.
-
Gamma correct the input image.
-
Create circuluar buffer. Pad the circular buffer with 0's simulating a 'border' for the pixels. Padding is necessary for error distribution to function properly when the output kernel is on an edge pixel without padding, error would be distributed to a location not allocated in memory.
-
Apply error correctly according to algorithm selected.
####halftone.cpp
usage: halftone infile m gamma outfile
m: select m * m cluster matrix where m <= 10
gamma: use 1.0 for no gamma correction.
-
Gamma correct the input image.
-
quantize the input image to n levels. Each pixel should now be represented by an m*m cluster matrix.
-
Compare each input pixel to a cluster dot matrix. If the quantized pixel value is greater than value found in cluster dot matrix, turn pixel value to 255, otherwise turn to 0.
Explanation of 4 deep for loops so I dont forget: The first 2 for loops will loop over the "big pixel" and the next 2 for loops will loop over the "small pixels". For each big pixel iteration, compare the input pixel m*m times against each entry in the cluster matrix. If the value of the quantized input pixel is larger than the value in the cluster matrix, then turn on the output pixel.
Here is where the magic happens:
for (int y=0; y<h; y++){
for (int x=0; x<w; x++) {
for (int j=0; j<m; j++) {
for (int i=0; i<m; i++){
out[(m*y*nh) + (j*nw) + i + (m*x)] = ((in[y*w+x] > clusterDot[i][j])] 255 : 0);
}
}
}
}(m * y * nh) + (j * nw) + i + (m * x) maps a 2d array to a 1d array. where each input pixel is now represented by an m * m cluster dot matrix.
usage: unordered_dither infile gamma n outfile where n is quantization levels.






