Skip to content

Repository files navigation

Coin Counter — AV3 / PDI

Automatic coin detection, counting and value estimation using classical Digital Image Processing techniques.

This project was developed for the PDI / Digital Image Processing course. The system receives an image containing Brazilian coins, applies a complete processing pipeline, detects coin candidates and estimates the final monetary value.

The project can be used in two main ways:

  1. Single image test — useful to visually inspect each Digital Image Processing step.
  2. Batch dataset evaluation — useful to randomly test 20% of a dataset and calculate accuracy metrics.

Techniques implemented

# Technique Purpose
1 Grayscale Conversion Reduces the image to one intensity channel
2 CLAHE / Contrast Enhancement Improves local contrast before segmentation
3 Gaussian Blur Reduces noise before thresholding
4 Adaptive + Otsu Thresholding Separates coin regions from the background
5 Morphological Operations Removes noise and fills small gaps
6 Contour Detection Detects object boundaries and coin candidates
7 Shape Filtering Filters candidates using area, circularity, solidity and aspect ratio
8 Hough Circle Transform Detects circular shapes and validates coin candidates
9 Watershed Segmentation Separates touching or overlapping regions
10 HSV Color Analysis Helps classify the monetary value of each coin
11 Candidate Fusion Combines contour, Hough and Watershed detections
12 Batch Evaluation Tests a random percentage of the dataset and calculates accuracy metrics

Project structure

Expected project structure:

pdi/
├── coin_test.py
├── coin_counter.py
├── batch_evaluate.py
├── generate_test_image.py
├── requirements.txt
├── README.md
└── pipeline_steps.png

Example dataset structure:

dataset/
├── classification_dataset/
│   └── all/
├── COCO_labelme_classification/
│   └── classification/
├── COCO_labelme_regression/
│   └── regression/
├── regression_dataset/
└── regression_sample/

The dataset folder does not need to be inside the project folder. However, the path used in the terminal commands must point correctly to where the dataset is located on your computer.


Main files

File Description
coin_test.py Main script for testing one image and visualizing the pipeline
coin_counter.py Alternative script for running the coin counter
batch_evaluate.py Script for automatic dataset evaluation
generate_test_image.py Generates a synthetic coin image for testing
requirements.txt Python dependencies
pipeline_steps.png Output image showing the processing steps

Requirements

Main dependencies:

opencv-python
numpy
matplotlib

Install them with:

pip install -r requirements.txt

Setup instructions

macOS / Linux setup

Open the terminal inside the project folder:

cd path/to/pdi

Example:

cd /Users/your_user/coding/Uni/pdi

Create a virtual environment:

python3 -m venv .venv

Activate the virtual environment:

source .venv/bin/activate

Install the dependencies:

python -m pip install --upgrade pip
python -m pip install -r requirements.txt

Test if OpenCV is working:

python -c "import cv2; print(cv2.__version__)"

If a version number appears, the setup is correct.


Windows setup

Open PowerShell or Command Prompt inside the project folder:

cd path\to\pdi

Example:

cd C:\Users\your_user\Documents\pdi

Create a virtual environment:

py -m venv .venv

Activate it:

PowerShell

.\.venv\Scripts\Activate.ps1

If PowerShell blocks the activation script, run:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\.venv\Scripts\Activate.ps1

Command Prompt

.venv\Scripts\activate

Install the dependencies:

python -m pip install --upgrade pip
python -m pip install -r requirements.txt

Test if OpenCV is working:

python -c "import cv2; print(cv2.__version__)"

If a version number appears, the setup is correct.


Single image usage

Use coin_test.py when you want to test one image and see the full visual pipeline.

This is the best option to understand how the PDI steps are working.


Testing one real image

macOS / Linux

python coin_test.py ../dataset/classification_dataset/all/5_1477290318.jpg

Windows

python coin_test.py ..\dataset\classification_dataset\all\5_1477290318.jpg

Important: the path depends on where your dataset is located.

If your dataset is not next to the pdi folder, use the full path.


Full path examples

macOS / Linux

python coin_test.py "/Users/your_user/coding/Uni/dataset/classification_dataset/all/5_1477290318.jpg"

Windows

python coin_test.py "C:\Users\your_user\Documents\dataset\classification_dataset\all\5_1477290318.jpg"

Testing one image without opening the visual window

Use --no-show if you only want the console result and do not want Matplotlib to open the figure window.

macOS / Linux

python coin_test.py ../dataset/classification_dataset/all/5_1477290318.jpg --no-show

Windows

python coin_test.py ..\dataset\classification_dataset\all\5_1477290318.jpg --no-show

Expected single-image output

The program prints a summary similar to this:

COIN COUNTER — RESULTS

[ contour ] color=copper_dark area=3246 radius=32.1 HSV=(21°, 227, 42) -> R$0.05

Raw contours:                  1
Valid contour candidates:       1
Fused candidates:               1
Hough Circles filtered:         1
Watershed objects filtered:     1
Final fused count:              1
Estimated Total Value:          R$ 0.05

The most important fields are:

Field Meaning
Raw contours Total raw contours found after segmentation
Valid contour candidates Contours that passed the shape filters
Fused candidates Final candidate list after merging detections
Hough Circles filtered Circular objects detected by Hough Circle Transform
Watershed objects filtered Objects detected after Watershed segmentation
Final fused count Final number of coins detected
Estimated Total Value Estimated monetary value in Brazilian reais

The script also saves:

pipeline_steps.png

This image shows the main processing steps used by the system.


Synthetic test image

If you do not have a real image available, you can generate a synthetic test image.

python generate_test_image.py

This creates:

coins.jpg

Then run:

python coin_test.py coins.jpg

or:

python coin_counter.py coins.jpg

Dataset filename convention

The batch evaluator estimates the expected value from the image filename.

Examples:

Filename example Expected value
5_1477290318.jpg R$0.05
10_1477290318.jpg R$0.10
25_1477290318.jpg R$0.25
50_1477290318.jpg R$0.50
100_1477290318.jpg R$1.00

This means that the first number before _ is interpreted as the coin class.


Batch dataset evaluation

The file batch_evaluate.py automatically evaluates multiple images from a dataset.

It can:

  1. Find images recursively inside a dataset folder.
  2. Randomly select a percentage of the dataset.
  3. Run the PDI pipeline on each selected image.
  4. Compare the detected result with the expected value from the filename.
  5. Generate counting accuracy metrics.
  6. Generate value estimation accuracy metrics.
  7. Save a CSV file.
  8. Save a summary report.
  9. Save annotated images.

Quick batch test with 200 images

This is recommended before running a full dataset evaluation.

macOS / Linux

python batch_evaluate.py ../dataset/classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

Windows

python batch_evaluate.py ..\dataset\classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

Explanation:

Argument Meaning
../dataset/classification_dataset Dataset folder to evaluate
--ratio 0.20 Randomly selects 20% of the available images
--seed 42 Makes the random selection reproducible
--max-images 200 Limits the test to 200 images
--save-images Saves annotated result images

Full 20% batch evaluation

To evaluate a true 20% random sample, remove --max-images.

macOS / Linux

python batch_evaluate.py ../dataset/classification_dataset --ratio 0.20 --seed 42 --save-images

Windows

python batch_evaluate.py ..\dataset\classification_dataset --ratio 0.20 --seed 42 --save-images

Evaluating different dataset folders

Depending on your dataset structure, each folder can be evaluated separately.

This is recommended because different dataset folders may have different image characteristics.


classification_dataset

macOS / Linux:

python batch_evaluate.py ../dataset/classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

Windows:

python batch_evaluate.py ..\dataset\classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

COCO_labelme_classification

macOS / Linux:

python batch_evaluate.py ../dataset/COCO_labelme_classification --ratio 0.20 --seed 42 --max-images 200 --save-images

Windows:

python batch_evaluate.py ..\dataset\COCO_labelme_classification --ratio 0.20 --seed 42 --max-images 200 --save-images

COCO_labelme_regression

macOS / Linux:

python batch_evaluate.py ../dataset/COCO_labelme_regression --ratio 0.20 --seed 42 --max-images 200 --save-images

Windows:

python batch_evaluate.py ..\dataset\COCO_labelme_regression --ratio 0.20 --seed 42 --max-images 200 --save-images

Evaluating the entire dataset folder

If you want to test all subfolders together:

macOS / Linux

python batch_evaluate.py ../dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

Windows

python batch_evaluate.py ..\dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

For the full 20% sample:

macOS / Linux

python batch_evaluate.py ../dataset --ratio 0.20 --seed 42 --save-images

Windows

python batch_evaluate.py ..\dataset --ratio 0.20 --seed 42 --save-images

Single-coin mode and multi-coin mode

By default, the batch evaluator assumes that the dataset images contain one coin per image.

This is correct for datasets such as:

classification_dataset
COCO_labelme_classification
COCO_labelme_regression

In this default mode, if the detector finds more than one candidate in a dataset image, the evaluator still checks whether the main coin was found correctly.

This is useful because these datasets are designed for classification/regression of one visible coin per image.


Multi-coin mode

If you want to evaluate images that may contain multiple coins in the same photo, use:

macOS / Linux

python batch_evaluate.py ../dataset --ratio 0.20 --seed 42 --max-images 200 --save-images --multi-coin-mode

Windows

python batch_evaluate.py ..\dataset --ratio 0.20 --seed 42 --max-images 200 --save-images --multi-coin-mode

Use --multi-coin-mode only when the images are expected to contain multiple coins.


Custom output folder

By default, batch results are saved in:

batch_results/

If you want to save the results of different experiments separately, use --output-dir.

Example:

python batch_evaluate.py ../dataset/classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images --output-dir results_classification

Windows:

python batch_evaluate.py ..\dataset\classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images --output-dir results_classification

Batch output files

After running batch_evaluate.py, the following folder is created:

batch_results/

Inside it, the main files are:

batch_results/evaluation_results.csv
batch_results/summary.txt
batch_results/annotated/
Output Description
evaluation_results.csv Detailed result for each tested image
summary.txt Accuracy summary
annotated/ Images with visual detection annotations

Opening the summary

macOS / Linux

cat batch_results/summary.txt

or:

open batch_results/summary.txt

Windows

type batch_results\summary.txt

You can also open the file manually using VS Code, Notepad or another text editor.


Understanding the batch metrics

The summary file contains metrics such as:

COUNT ACCURACY
--------------
Contour Detection accuracy
Hough Circle accuracy
Watershed accuracy
Fused Candidate accuracy
Final Count accuracy

VALUE ACCURACY
--------------
Rule-based value accuracy
Calibrated value accuracy
Color+area value accuracy

Count metrics

Metric Meaning
Contour Detection accuracy Accuracy using only contour candidates
Hough Circle accuracy Accuracy using only Hough Circle Transform
Watershed accuracy Accuracy using only Watershed segmentation
Fused Candidate accuracy Accuracy after merging candidate detections
Final Count accuracy Final counting accuracy used as the main result

The most important counting metric is:

Final Count accuracy

Value metrics

Metric Meaning
Rule-based value accuracy Value accuracy using fixed color/area rules
Calibrated value accuracy Value accuracy using area calibration from the dataset
Color+area value accuracy Value accuracy combining color and detected area

The value classification is harder than counting because it depends on:

  • illumination;
  • shadows;
  • reflections;
  • coin color variation;
  • image scale;
  • visual similarity between coin classes.

Therefore, the system is expected to perform better in coin counting than in monetary value classification.


Current experimental results

The following results were obtained using a random sample of 200 images with seed 42.

The tests were executed separately for each dataset folder.


classification_dataset

Valid processed images: 200
Errors: 0

COUNT ACCURACY
--------------
Contour Detection accuracy:        90.00%
Hough Circle accuracy:             79.00%
Watershed accuracy:                64.50%
Fused Candidate accuracy:          88.00%
Final Count accuracy:              100.00%

VALUE ACCURACY
--------------
Rule-based value accuracy:         50.00%
Calibrated value accuracy:         60.00%
Color+area value accuracy:         56.00%
Rule-based mean abs. value error:  R$ 0.19
Calibrated mean abs. value error:  R$ 0.16
Color+area mean abs. value error:  R$ 0.17

Per-class results:

R$ 0.05: count_acc=100.00%, value_acc_calibrated=46.51%
R$ 0.10: count_acc=100.00%, value_acc_calibrated=68.89%
R$ 0.25: count_acc=100.00%, value_acc_calibrated=58.06%
R$ 0.50: count_acc=100.00%, value_acc_calibrated=46.15%
R$ 1.00: count_acc=100.00%, value_acc_calibrated=78.57%

COCO_labelme_classification

Valid processed images: 200
Errors: 0

COUNT ACCURACY
--------------
Contour Detection accuracy:        88.50%
Hough Circle accuracy:             78.00%
Watershed accuracy:                58.50%
Fused Candidate accuracy:          90.00%
Final Count accuracy:              99.50%

VALUE ACCURACY
--------------
Rule-based value accuracy:         44.50%
Calibrated value accuracy:         47.50%
Color+area value accuracy:         49.50%
Rule-based mean abs. value error:  R$ 0.21
Calibrated mean abs. value error:  R$ 0.21
Color+area mean abs. value error:  R$ 0.20

Per-class results:

R$ 0.05: count_acc=97.50%, value_acc_calibrated=37.50%
R$ 0.10: count_acc=100.00%, value_acc_calibrated=60.00%
R$ 0.25: count_acc=100.00%, value_acc_calibrated=50.00%
R$ 0.50: count_acc=100.00%, value_acc_calibrated=25.00%
R$ 1.00: count_acc=100.00%, value_acc_calibrated=74.29%

COCO_labelme_regression

Valid processed images: 200
Errors: 0

COUNT ACCURACY
--------------
Contour Detection accuracy:        63.50%
Hough Circle accuracy:             44.00%
Watershed accuracy:                41.00%
Fused Candidate accuracy:          54.00%
Final Count accuracy:              80.00%

VALUE ACCURACY
--------------
Rule-based value accuracy:         45.69%
Calibrated value accuracy:         53.45%
Color+area value accuracy:         50.00%
Rule-based mean abs. value error:  R$ 0.31
Calibrated mean abs. value error:  R$ 0.22
Color+area mean abs. value error:  R$ 0.27

Per-class results:

R$ 0.05: count_acc=95.83%, value_acc_calibrated=50.00%
R$ 0.10: count_acc=95.45%, value_acc_calibrated=72.73%
R$ 0.25: count_acc=100.00%, value_acc_calibrated=52.38%
R$ 0.50: count_acc=100.00%, value_acc_calibrated=40.00%
R$ 1.00: count_acc=87.50%, value_acc_calibrated=54.17%

Result analysis

The experimental results show that the system performs better in coin detection and counting than in monetary value classification.

The best counting results were obtained in:

classification_dataset
COCO_labelme_classification

In these folders, the final counting accuracy reached approximately 100% in the sampled evaluation.

The value estimation task was more difficult. This is expected because Brazilian coins may have similar colors and sizes, and the images contain variations in:

  • lighting;
  • shadows;
  • reflections;
  • scale;
  • coin position;
  • background texture.

The system still provides value estimation, but the value accuracy is lower than the counting accuracy.


Recommended command sequence for evaluation

A complete evaluation workflow is:

1. Activate the virtual environment

macOS / Linux:

source .venv/bin/activate

Windows PowerShell:

.\.venv\Scripts\Activate.ps1

2. Test a single image

macOS / Linux:

python coin_test.py ../dataset/classification_dataset/all/5_1477290318.jpg

Windows:

python coin_test.py ..\dataset\classification_dataset\all\5_1477290318.jpg

3. Run a quick batch evaluation

macOS / Linux:

python batch_evaluate.py ../dataset/classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

Windows:

python batch_evaluate.py ..\dataset\classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images

4. Read the summary

macOS / Linux:

cat batch_results/summary.txt

Windows:

type batch_results\summary.txt

Troubleshooting

ModuleNotFoundError: No module named 'cv2'

This means OpenCV was not installed in the Python environment being used.

Make sure the virtual environment is activated, then run:

python -m pip install -r requirements.txt

Then test:

python -c "import cv2; print(cv2.__version__)"

FileNotFoundError: Could not load image

This usually means the image path is wrong.

Check if the file exists.

macOS / Linux:

ls ../dataset/classification_dataset/all

Windows:

dir ..\dataset\classification_dataset\all

If the dataset is in another location, use the full path.


The command works on one computer but not on another

Paths are different on each computer.

Example macOS path:

/Users/your_user/coding/Uni/dataset/classification_dataset/all/5_1477290318.jpg

Example Windows path:

C:\Users\your_user\Documents\dataset\classification_dataset\all\5_1477290318.jpg

Use quotation marks if the path contains spaces:

python coin_test.py "/Users/your_user/My Dataset/image.jpg"

Windows:

python coin_test.py "C:\Users\your_user\My Dataset\image.jpg"

Batch results are being overwritten

By default, each batch run writes to:

batch_results/

To avoid overwriting previous results, use a different output folder:

python batch_evaluate.py ../dataset/classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images --output-dir results_classification

Windows:

python batch_evaluate.py ..\dataset\classification_dataset --ratio 0.20 --seed 42 --max-images 200 --save-images --output-dir results_classification

Conclusion

This project demonstrates a complete classical Digital Image Processing pipeline for coin detection, counting and value estimation.

The system uses grayscale conversion, contrast enhancement, Gaussian blur, adaptive thresholding, morphological operations, contour detection, Hough Circle Transform, Watershed segmentation, HSV color analysis and candidate fusion.

The best results were obtained for coin counting, reaching very high accuracy in the classification datasets. Monetary value estimation was more challenging because it depends on color, scale and lighting conditions.

Overall, the project shows that classical Digital Image Processing techniques can be combined to build a functional coin detection and counting system without requiring a trained deep learning model.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages