Classification of 11 planets and moons from images, using handcrafted image features and three classic machine learning models (Decision Tree, SVM, and Logistic Regression). No deep learning is involved.
This was a university project for an Artificial Intelligence course (Universitas Teknologi Bandung).
The best model is the Decision Tree, with 97.26% accuracy on the test set (319 of 328 images).
| Model | Accuracy | Precision | Recall | F1-Score |
|---|---|---|---|---|
| Decision Tree | 97.26% | 97.31% | 97.26% | 97.26% |
| Logistic Regression | 68.29% | 67.88% | 68.29% | 67.86% |
| SVM (RBF kernel) | 59.76% | 59.85% | 59.76% | 58.58% |
Precision, recall, and F1-score are weighted averages over the 11 classes. The test set contains 328 images, so one image is about 0.3 percentage points.
Confusion matrices for each model are in the results/ folder.
| Step | Script | What it does |
|---|---|---|
| 1. Preprocessing | 1_preprocessing.py |
Loads the images in grayscale at their original size and splits them 80/20 into training (1,310) and test (328) sets, stratified by class (random_state=42). |
| 2. Feature extraction | 2_feature_extraction.py |
Converts each image into a 100-value feature vector (see below). |
| 3. Training | 3_train_models.py |
Trains an SVM (RBF kernel), Logistic Regression, and a Decision Tree with scikit-learn, mostly with default settings. |
| 4. Evaluation | 4_evaluate_compare.py |
Computes accuracy, precision, recall, and F1-score, then saves the comparison chart, confusion matrices, and metrics to results/. |
Features (100 values per image):
- Intensity histogram: 64 values (normalized)
- Edge histogram from Canny edge detection: 32 values (normalized)
- Intensity statistics: 4 values (mean, standard deviation, minimum, maximum)
- Results come from a single train/test split. There is no cross-validation or hyperparameter tuning, and the best model is chosen on the same test set.
- The SVM and Logistic Regression were trained on unscaled features. The intensity statistics (0-255) are much larger than the histogram values (below 1), which likely explains their lower scores. The Decision Tree is not affected by feature scale.
- The Canny output only contains the values 0 and 255, so most of the 32 edge histogram bins are always zero. In practice it carries about one number: the fraction of edge pixels.
- Duplicate or near-duplicate images between the training and test sets were not checked.
Celestial-Object-Classification
├── data/ # dataset (not included, see Getting Started)
├── results/ # charts, confusion matrices, and metrics
├── 1_preprocessing.py
├── 2_feature_extraction.py
├── 3_train_models.py
├── 4_evaluate_compare.py
├── check_dataset.py # prints the number of images per class
├── requirements.txt
├── LICENSE
└── README.md
Requires Python 3.11 or newer.
1. Clone the repository and install the dependencies
git clone https://github.com/SidqiRaafi/celestial-object-classification.git
cd celestial-object-classification
python -m venv venv
# Windows: .\venv\Scripts\activate
# macOS/Linux: source venv/bin/activate
pip install -r requirements.txt2. Download the dataset
Download the Planets and Moons Dataset from Kaggle (1,638 images, 11 classes) and extract it into data/ with one folder per class:
data/
├── <class_name_1>/
│ ├── image_001.jpg
│ └── ...
└── <class_name_2>/
└── ...
You can check the result with python check_dataset.py.
3. Run the pipeline
python 1_preprocessing.py
python 2_feature_extraction.py
python 3_train_models.py
python 4_evaluate_compare.pyRun the scripts from the project root, in order. The first three save intermediate .pkl files in the project root, and the last one writes its output to results/.
Data: Planets and Moons Dataset - AI in Space on Kaggle. Please check the dataset's license terms before reusing it.
Code: released under the MIT License.
Sidqi Raafi Al Fauzan, Informatics Engineering, Universitas Teknologi Bandung - GitHub
