Each pixel is traversed via two for-loops. The value of all three BGR channels of the pixel is set as the weighted average of all combined channels: (B*0.11) + (G*0.59) + (R*0.30). The result is a grayscale version of the original image.

Trendy Waves:

Albeit more complicated than a simple grayscale conversion, the process begins just the same with the traversal of all image pixels via two for-loops. The difference arises when we decide which regions to color a certain hue. A curve is created implementing a simple sine function using the x-coordinates (or columns) of the image matrix. The user-preferred period and amplitude of the curve is applied to the formula and the function's output is rounded to the nearest integer since pixels are of whole numbers. If the current row we are traversing is equal to the output of the rounded sine wave based on the current column, we update the pixel with a high saturation of either blue, green, or red depending on how far down the image is.

To create the fill effect of thick colored waves, we maintain an array 'M' indexed 0 to n-1 where n is the width of the original image. M[i] will provide the color of and row at which the ith pixel along the sine wave was drawn. For each pixel that does not lie on the original wave, we keep track of how far below the sine wave it is. If the distance between the current row and the sine wave above it is less than the user-defined 'thickness' variable, the pixel is saturated with the same color as the above curve. If the distance between the current pixel's row and the sine wave above surpasses the 'thickness' variable, we reassign M[current_column] to our current row and switch the color. This effectively resets where the addressable curve is for pixels below the current pixel. The process repeats until the entire image is colored, leaving several trendy programmable curves. Neat!