Image processing utilities for handling PPM (Portable Pixmap) format images, as defined by the Netpbm format. It includes functions for image concatenation (vertically and horizontally), rotation, and generating visual patterns from Pascal's triangle with color modulation. Designed to be purely functional, avoids side effects and mutable state.
- Ensure that
Scala
andsbt
are installed on your machine. - The main functions are encapsulated in
Solution.scala
, with utily types and functions defined in:util/Util.scala
andutil/Pixel.scala
.
- PPM files start with the header
P3
, indicating the PPM format, followed by the image'swidth
andheight
, and the maximum color value, which is always255
. - Each pixel's RGB values are listed sequentially, one pixel per line, with no additional spaces after the blue value.
Pixel
holds integer RGB values.- Images are a list of lists of Pixel objects:
- (
Image = List[List[Pixel]]
)
- (
- Grayscale image witha gray filter, contains double precision values:
- (
GrayscaleImage = List[List[Double]]
)
- (
- Vertical Concatenation: Combines two images of the same width into one, with the first image on the top and the second on the bottom.
- Horizontal Concatenation: Joins two images of the same height side by side, with the first image on the left and the second on the right.
- Image Rotation: Rotates an image by multiples of 90 degrees counterclockwise.
The Sobel Edge Detection
applies a series of steps to detect edges within an image. It onverts the image to grayscale, applying Gaussian blur to smooth the image, using the Sobel operator to detect edge gradients, combining these gradients to highlight edges, and applying a threshold to distinguish edges clearly.
Example: (how the convolution is performed on matrixes)
Grayscale Conversion: simplifies an image to shades of gray, reducing complexity and focusing on intensity, which is crucial for the effectiveness of blur and edge detection processes.
Gaussian Kernel: applied to the image using a convolution kernel, which is a matrix of weights. The Blur Gaussian kernel is determined based on the Gaussian function, it assigns higher weights to pixels closer to the center of the kernel and lower weights to those further away.
Convolution Process: each pixel is recalculated using a weighted average of itself and surrounding pixels based on the Gaussian kernel. The convolution with these intensity edge kernels adjusts the brightness of each pixel based on its neighbors, the result is softened edges.
Edge Detection: reducing noise and softening the image, Gaussian blurring makes it easier to identify significant transitions in intensity, which correspond to edges in the image which relies on these transitions to outline the important structures within the image.
The Pascal's Triangle
displays a fractal-like aspect when colored with a modulo operation, revealing self-repeating patterns that emerge from simple reccursion rules.
The simplest way to describe a line in Pascal's Triangle is:
- The first and last element is always 1, described by
$l_0 = l_n = 1$ . - For the rest of the elements in the triangle, the recursion
$l_i = l_{i-1}^p + l_i^p$ is used, where$l$ is the current line, and$l^p$ is the previous line.
Colors are defined by Pixel
object value, with the pickColor
function determining the color mapping. Any values above the main diagonal default to black, remaining unaltered by pickColor
.
Note: that a value on line
Pascal's Triangle with modulo operations generates visual patterns, where the modulus value