Skip to content

madrazaldi/PCD_Assignment03

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

This project implements classical binary segmentation and morphological image processing from scratch, without using specialized image-processing libraries (no OpenCV, skimage, scipy, etc).

Only Pillow (for I/O), NumPy (array storage), and Matplotlib (optional visualization) are used.

The goal is to:

  1. Implement one segmentation method

  2. Implement several morphological operations

  3. Compare segmentation results before and after morphology

  4. Output both images and numeric metrics

1. Objective

Segmentation via global thresholding often produces noisy binary masks, especially on natural images.

Morphological operators—erosion, dilation, opening, closing—can improve the mask by removing noise, filling holes, and simplifying boundaries.

This project performs:

  • Segmentation: Otsu’s automatic global threshold (from scratch)

  • Morphology:

    • Erosion

    • Dilation

    • Opening (erosion → dilation)

    • Closing (dilation → erosion)

All algorithms implemented manually with nested loops.

2. Input Image

The input for this experiment was a photograph (Harambe image).

It was converted to 8-bit grayscale (0–255).

3. Segmentation Method (Implemented From Scratch)

Otsu’s Global Threshold

Otsu chooses a threshold $t^*$ maximizing between-class variance:

$\sigma_b^2(t) = \omega_0(t)\omega_1(t)\left(\mu_0(t)-\mu_1(t)\right)^2$

The image is then binarized:

if pixel > t*: foreground (1)
else: background (0)

Polarity Selection

Because foreground may be either bright or dark, the code evaluates both:

  • bright foreground = $img > t$

  • dark foreground = $img < t$

Then selects the mask with a better foreground ratio.

Actual Results

Otsu threshold: 101
Chosen polarity: bright>thr
Foreground ratio (bright>thr): 49.2%
Foreground ratio (dark<thr):   50.3%

This means the image is roughly balanced, so either polarity produces similar results, but the algorithm selected bright > threshold.

4. Morphological Operations (Implemented From Scratch)

Using a 5×5 cross-shaped structuring element:

  • Erosion: Removes isolated foreground pixels and shrinks boundaries.

  • Dilation: Grows regions; fills small gaps.

  • Opening = erosion → dilation: Removes small bright noise (“salt noise”).

  • Closing = dilation → erosion: Fills small dark holes (“pepper noise”) and smooths shapes.

5. Quantitative Comparison

The script computes:

  • sum: number of foreground pixels

  • fg%: percentage of foreground

  • components: 4-connected components

  • perimeter: approximate boundary length (4-neighborhood)

Segmented (raw)            sum=   1935120  fg%= 49.21  comps=  3100  perim= 188732
After Opening              sum=   1860919  fg%= 47.33  comps=   838  perim= 153484
After Closing              sum=   1893324  fg%= 48.15  comps=   803  perim= 123694
XOR Seg vs Open            sum=     74201  fg%=  1.89  comps= 13334  perim=  65986
XOR Open vs Close          sum=     51987  fg%=  1.32  comps=   9627  perim=  47532

6. Analysis of Results

Massive Noise Reduction

Foreground components dropped dramatically:

Stage # Components
Raw Segmentation 3100
After Opening 838
After Closing 803

This is a 74% reduction after opening and almost 75% after closing — meaning the mask becomes significantly cleaner.

Boundary Simplification

Perimeter (4-neighbor boundary length) decreased:

Stage Perimeter
Raw 188,732
After Opening 153,484
After Closing 123,694

Closing smooths the boundaries further (–34% vs raw).

Pixel-Level Change Analysis

XOR maps show how much morphology changed:

Comparison Changed Pixels % Interpretation
Seg → Open 74,201 1.89% Opening removed speckles / small blobs
Open → Close 51,987 1.32% Closing filled holes & gaps

Even though these are small percentages, they happen in high-value regions (boundaries and noise clusters), noticeably improving segmentation quality.

7. Visual Comparison

Original

Original

Raw Segmentation

Segmented

After Opening

Opening

After Closing

Closing

Change Maps (XOR)

Seg vs Open Open vs Close

8. Conclusion

  • Otsu segmentation alone produces a noisy binary mask on natural images.

  • Opening drastically removes small bright noise and reduces fragment clusters.

  • Closing fills small holes and smooths boundaries further.

  • Component count dropped from 3100 → 803 showing significant structural improvement.

  • Perimeter dropped from 188k → 123k, indicating smoother, cleaner shapes.

  • XOR maps confirm meaningful modifications while preserving overall structure.

In conclusion, morphological post-processing clearly produces a more stable, cleaner segmentation result.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages