Skip to content

Repository files navigation

Sparse Representation for Image Classification Using Global and Local Texture Features

Research code for the dissertation project Sparse Representation for Image Classification Using Global and Local Texture Features.

Item Information
Student Zixin Ding
Student ID 20513868
Supervisor Dr. Jianfeng Ren
Academic Year 2025/2026

This repository implements Sparse Global-Local Texture Representation Classification (SGLT-RC), a hybrid image-classification framework for small-sample object recognition. It combines a pretrained global deep descriptor, an interpretable local texture descriptor, feature-level fusion, and Lasso-based sparse representation classification.


1. Abstract

Image classification has advanced substantially through deep convolutional networks and transfer learning. However, reliable recognition remains challenging when only a limited number of labelled training samples are available for each class. In such settings, pretrained deep descriptors can provide strong semantic representations, while local texture patterns and spatial appearance cues may still contain complementary information that is not fully captured by a global deep feature alone.

Motivated by this gap, this dissertation proposes Sparse Global-Local Texture Representation Classification (SGLT-RC), a hybrid image-classification framework that combines pretrained global representation, interpretable local texture encoding, feature-level fusion, and Lasso-based sparse representation classification.

The implemented main route is:

resnet50 + lbp_basic_spatial25 + src_standard

In this route, the global branch extracts a 2048-dimensional pretrained ResNet50 descriptor, while the local branch extracts a project-authored Basic Shifted-Grid Pyramid Local Binary Pattern descriptor, implemented as lbp_basic_spatial25. The local descriptor is built from a basic 8-neighbor LBP code map, a 4 x 4 main grid, a half-cell shifted 3 x 3 auxiliary grid, and 25 regional histograms, producing a 6400-dimensional local descriptor. The two descriptors are concatenated into an 8448-dimensional fused feature and classified using the standard L1-SRC implementation, src_standard, by comparing class-wise reconstruction residuals.

The repository includes dataset preprocessing, split generation, feature extraction, descriptor caching, evaluation scripts, JSON metric logging, paper-section experiment wrappers, figure-generation scripts, and optional bridges for MATLAB-side dictionary-learning comparisons. Experiments are organized around Caltech-101 and COIL-100, with repeated split protocols, feature ablations, classifier comparisons, sparse-parameter sensitivity checks, runtime recording, and result-table / figure support.


2. Proposed Framework

The main SGLT-RC implementation route is:

resnet50 + lbp_basic_spatial25 + src_standard

Architecture

Component Dissertation term Implementation name Role
Global branch ResNet50 global descriptor resnet50 2048-D pretrained deep feature
Local branch Basic Shifted-Grid Pyramid LBP lbp_basic_spatial25 6400-D local texture descriptor
Fusion Global-local feature concatenation resnet50+lbp_basic_spatial25 8448-D fused feature
Classifier L1 sparse representation classifier src_standard class-wise residual prediction
Framework Sparse Global-Local Texture Representation Classification SGLT-RC proposed global-local sparse framework

The local branch is summarized here because it is the main project-specific descriptor design. Detailed feature aliases and comparison variants are listed later in Section 4.1.

RGB image
-> grayscale image
-> Basic LBP code map
-> 4 x 4 main grid + shifted 3 x 3 auxiliary grid
-> 25 regional histograms
-> concatenate + L2 normalize
-> 6400-D local descriptor

In this README, Basic Shifted-Grid Pyramid LBP refers to the implemented lbp_basic_spatial25 descriptor: a basic 8-neighbor LBP code map is partitioned by a 4 x 4 main grid and a half-cell shifted 3 x 3 auxiliary grid, giving 16 + 9 = 25 regions. A 256-bin histogram is computed for each region, and the regional histograms are concatenated into the final 6400-D local descriptor.

Other LBP variants, ridge residual classification, nearest-neighbour classification, and dictionary-learning baselines are included as comparison lines for ablation, robustness checks, and runtime analysis.


3. Setup and Core Pipeline

3.1 Environment

The Python pipeline is developed around Python 3.12.

conda create -n fyp-image-cls python=3.12 -y
conda activate fyp-image-cls
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

MATLAB is only needed for optional external comparison workflows such as LC-KSVD or D-KSVD. The main SGLT-RC pipeline is implemented in Python.

A quick syntax check after installation or code editing is:

python -m compileall src scripts

3.2 Datasets

This repository evaluates two object-recognition datasets. The train/test split protocol is aligned with Locality-Aware Discriminative Subspace Learning for Image Classification (LADSL; Meenakshi and Srirangarajan, 2022), while features are re-extracted in this project from the raw images.

Dataset Summary Source Expected raw path Split protocol
Caltech-101 101 object categories; around 40-800 images per category CaltechDATA data/raw/caltech101/101_ObjectCategories/ Tr = {10, 15, 20, 25}, 10 repeated splits; BACKGROUND_Google excluded
COIL-100 100 objects, 72 views per object, 7,200 color images Columbia CAVE data/raw/coil-100/ Tr = {1, 2, 3, 10, 20, 30}, 10 repeated splits

Raw datasets are not expected to be committed to Git. They should be placed manually under the expected data/raw/ paths before preprocessing.

Preprocessing writes manifests, reusable split CSV files, and dataset-specific cached files under data/processed/ and data/splits/. For COIL-100, the preprocessing code also keeps a protocol-compatible raw32 path with grayscale conversion, 32 x 32 resizing, and unit-norm normalization.

Dataset example figures are expected under:

  • docs/images/caltech101_examples.png: representative raw images from different Caltech-101 classes
  • docs/images/coil100_examples.png: representative raw images from different COIL-100 object classes

Regenerate them with:

python scripts/paper/figures/create_dataset_examples_figure.py

3.3 Core Pipeline Overview

The practical running flow is:

raw dataset folders
-> preprocessing and split CSV generation
-> feature extraction or cache reuse
-> feature fusion through feature expressions
-> classifier evaluation
-> JSON metric files
-> paper figures / summaries

A typical reviewer workflow is:

  1. install dependencies;
  2. place raw datasets under data/raw/;
  3. preprocess the selected dataset;
  4. run a quick one-split evaluation to verify the pipeline;
  5. run the main SGLT-RC configuration or paper-section wrappers.

3.4 Step 1: Preprocess Datasets

python -m src.preprocessing.run_preprocess --dataset [dataset] --seed [seed]

Examples:

python -m src.preprocessing.run_preprocess --dataset caltech101 --seed 42
python -m src.preprocessing.run_preprocess --dataset coil100 --seed 42
Option Values Purpose
--dataset caltech101, coil100 choose dataset-specific preprocessing
--seed integer control repeated split generation
--train-counts integers override default train-count protocol
--repeats integer override number of repeated splits
--width, --height integers size for the COIL-100 raw32 path

Expected outputs include:

  • data/processed/<dataset>/ summaries and manifests;
  • data/splits/<dataset>/ reusable train/test CSV files.

3.5 Step 2: Run a Quick Pipeline Check

A lightweight check can use ResNet50 with nearest-neighbour classification and only one split per train-count setting:

python -m src.evaluation.run_evaluation --dataset caltech101 --mode extended --feature resnet50 --classifier nnc --max-splits-per-train-count 1 --seed 42

Expected behaviour:

  • load the generated split CSV files;
  • extract or reuse the selected descriptors;
  • write a JSON result under results/metrics/caltech101/;
  • record per-split accuracy, aggregate accuracy, command configuration, and timing.

3.6 Step 3: Run the Main SGLT-RC Configuration

python -m src.evaluation.run_evaluation --dataset [dataset] --mode extended --feature resnet50+lbp_basic_spatial25 --classifier src_standard --lasso-alpha 1e-5 --lasso-max-iter 10000 --seed 42

Example main-method runs:

python -m src.evaluation.run_evaluation --dataset caltech101 --mode extended --feature resnet50+lbp_basic_spatial25 --classifier src_standard --lasso-alpha 1e-5 --lasso-max-iter 10000 --seed 42

python -m src.evaluation.run_evaluation --dataset coil100 --mode extended --feature resnet50+lbp_basic_spatial25 --classifier src_standard --lasso-alpha 1e-5 --lasso-max-iter 10000 --seed 42

For a shorter test run, add:

--max-splits-per-train-count 1

src_standard can be much slower than nnc or src_ridge, especially for high-dimensional fused features. The JSON outputs support resume-style behaviour: if a compatible result file already exists with completed rows, only missing rows are evaluated.

Option Values Purpose
--dataset caltech101, coil100 choose dataset
--mode paper_aligned, extended paper_aligned restricts to nnc; extended enables all project classifiers
--feature any feature expression from Section 4.1 choose feature vector or feature fusion
--classifier nnc, src_ridge, src_standard, dksvd, aliases src, src_l1 choose classifier
--lasso-alpha float, e.g. 1e-5 L1 regularization for src_standard
--lasso-max-iter integer maximum Lasso iterations for src_standard
--ridge-lambda float, e.g. 1e-3 ridge penalty for src_ridge
--src-standard-n-jobs integer, -1, or omitted worker count for src_standard; lower values reduce memory pressure
--src-ridge-n-jobs integer, -1, or omitted worker count for src_ridge
--max-splits-per-train-count integer quick-run limiter for each train-count setting
--output-group path fragment subfolder under results/metrics/<dataset>/
--save-predictions flag store labels and predictions for confusion matrices

3.7 Step 4: Run One Representative Train-Count Row

python scripts/run_selected_train_count_eval.py --dataset [dataset] --mode extended --train-count [Tr] --max-runs [N] --feature [feature] --classifier [classifier] --output-group [group] --seed [seed]

Example:

python scripts/run_selected_train_count_eval.py --dataset caltech101 --mode extended --train-count 10 --max-runs 10 --feature resnet50+lbp_basic_spatial25 --classifier src_standard --lasso-alpha 1e-5 --lasso-max-iter 10000 --output-group paper_sections/01_feature_ablation/20_tr10_clean --seed 42
Option Values Purpose
--train-count integer fixed Tr setting, such as 10 for Caltech-101 or 2 for COIL-100
--max-runs integer number of repeated splits to run
--feature feature expression same feature naming as Section 4.1
--classifier nnc, src_standard, src_ridge classifier for this fixed-Tr runner
--output-group path fragment paper-section subfolder for the JSON output
--save-predictions flag save per-sample predictions for confusion matrix plotting

3.8 Step 5: Paper Workflow Wrappers

bash scripts/paper/run_paper_local_sections.sh
bash scripts/paper/run_paper_autodl_sections.sh

4. Feature and Classifier Reference

4.1 Feature Options

Feature dimensions assume the default LBP setting P=8, R=1.0.

Feature naming follows this convention:

  • global means one histogram is extracted from the whole image.
  • spatial16 means the image is divided into a regular 4 x 4 grid and one histogram is extracted per region.
  • spatial25 means the shifted-grid layout used by Basic Shifted-Grid Pyramid LBP: a 4 x 4 main grid plus a half-cell shifted 3 x 3 auxiliary grid.
  • basic keeps the standard 256-bin LBP code histogram.
  • circular_uniform uses a compact uniform-pattern LBP histogram. It is lower-dimensional and useful as an efficiency-oriented comparison.
Code name Descriptor type Dimension Notes
raw32 grayscale raw vector 1024 COIL-100 only; 32 x 32 unit-norm vector
resnet50 global deep descriptor 2048 pretrained ResNet50 feature
lbp basic global LBP 256 legacy alias for lbp_basic_global
spatial_lbp legacy 25-region basic pyramid-LBP 6400 backward-compatible alias, not the preferred method name
lbp_basic_global basic LBP, whole-image histogram 256 local texture without spatial partitioning
lbp_basic_spatial16 basic pyramid-LBP, 4 x 4 regions 4096 16 x 256 regional histograms
lbp_basic_spatial25 Basic Shifted-Grid Pyramid LBP 6400 main local descriptor, 25 x 256 regional histograms
lbp_basic_spatial25_legacy older 25-region basic layout 6400 compatibility check for legacy experiments
lbp_circular_uniform_global circular-uniform LBP, whole-image histogram 10 compact local texture descriptor
lbp_circular_uniform_spatial16 circular-uniform pyramid-LBP, 4 x 4 regions 160 16 x 10 regional histograms
lbp_circular_uniform_spatial25 circular-uniform pyramid-LBP, 25 regions 250 25 x 10 regional histograms

Feature components can be concatenated with +:

resnet50+lbp_basic_spatial25
raw32+lbp_basic_global

4.2 Classifier Options

Code name Classifier Main parameters Use in this project
nnc nearest-neighbour classifier none simple baseline
src_standard L1 sparse representation classifier --lasso-alpha, --lasso-max-iter, --src-standard-n-jobs main sparse classifier line
src_ridge ridge residual classifier --ridge-lambda, --src-ridge-n-jobs fast residual comparison line
dksvd practical D-KSVD style classifier --dksvd-atoms, --dksvd-sparsity, --dksvd-iters, --dksvd-code-algorithm optional dictionary-learning comparison
src legacy alias maps to src_ridge in run_evaluation compatibility only
src_l1 legacy alias maps to src_standard in run_evaluation compatibility only

Classifier differences:

  • nnc is the simplest nearest-neighbour baseline. It checks whether the feature itself is discriminative without adding a representation model.
  • src_standard is the main sparse representation classifier. It solves an L1 Lasso problem for each test sample, then assigns the class with the lowest reconstruction residual. It is closest to classic SRC, but it is sensitive to --lasso-alpha and can be slow for high-dimensional spatial LBP features.
  • src_ridge replaces the L1 sparse solver with ridge-regularized residual prediction. It is faster and more stable, but it is not strictly sparse, so it is treated as a practical residual-classifier comparison rather than the main method.
  • dksvd is an optional dictionary-learning comparison line. It is included for experimental completeness, not as the core contribution.

5. Results and Output Entry Points

Main generated outputs are written to:

Purpose Path
Manifests, summaries, descriptor caches, gray vectors data/processed/<dataset>/
Reusable train/test CSV files data/splits/<dataset>/
Main JSON experiment metrics results/metrics/<dataset>/
Paper-section organized metrics results/metrics/<dataset>/paper_sections/
Generated plots and confusion matrices results/figures/
Method and dataset figures docs/images/
Optional MATLAB-side exports results/matlab_exports/<dataset>/

The JSON outputs are the primary experiment artifacts. They record:

  • dataset and split protocol;
  • feature expression and feature components;
  • classifier and hyperparameters;
  • seed and command line;
  • per-split accuracy;
  • average accuracy by train-count;
  • overall mean and standard deviation;
  • timing and completion status.

Many scripts support resume-style behaviour: if a target JSON already exists and has completed rows, only missing rows are filled in. Supporting documentation for comments, input/output data, verification checks, and external-code boundaries is summarized in docs/submission_documentation.md.


6. Project Structure

Organized by data, implementation, scripts, documentation, and generated results.

Root project
fyp_image_classification_project/
|-- README.md                      # project overview and running guide
|-- requirements.txt               # Python dependency list
|-- .gitignore                     # ignored generated files and local artifacts
data/ - raw data, processed metadata, and splits
data/
|-- raw/                           # user-provided raw dataset copies
|  |-- caltech101/                 # expected Caltech-101 archive layout
|  `-- coil-100/                   # expected COIL-100 flat image directory
|-- processed/                     # generated summaries, gray vectors, descriptor caches
`-- splits/                        # train/test CSV files reused by evaluations
src/ - reusable Python implementation
src/
|-- datasets/                      # dataset-specific preprocessing and protocols
|-- preprocessing/                 # manifest and split generation utilities
|-- features/                      # ResNet50 and LBP-family extractors
|-- classifiers/                   # nnc, src_standard, src_ridge, dksvd
|-- evaluation/                    # CLI evaluation pipeline and feature routing
|-- bridges/                       # helpers for external / cross-runtime workflows
`-- utils/                         # path, seed, and result-format helpers
scripts/ - runnable experiment entrypoints
scripts/
|-- run_selected_train_count_eval.py     # fixed train-count evaluation runner
|-- precompute/                          # preprocessing and descriptor-cache helpers
|-- paper/                               # dissertation workflow orchestration and figures
|-- bridge/                              # MATLAB export helpers
|-- organize_paper_section_results.py    # result organization utility
|-- bootstrap_caltech101_tr10_sections.py
`-- bootstrap_coil100_tr2_sections.py
docs/ and results/ - writing assets and generated outputs
docs/
|-- images/                        # method and dataset figures

results/
|-- metrics/                       # JSON experiment metrics
|-- figures/                       # generated plots and confusion matrices
`-- matlab_exports/                # optional MATLAB-side matrices and summaries
external/ - optional external references
external/                          # optional MATLAB references and project wrappers
|-- README.md                      # external-code boundary and citations
`-- project_wrappers/              # project-authored MATLAB batch wrappers

The core Python pipeline does not require third-party MATLAB code. Only external/README.md and external/project_wrappers/ are intended as project-authored submission material. Third-party LC-KSVD, D-KSVD, KSVDBox, OMPBox, and spatial-pyramid reference folders may exist locally, but they are ignored by Git and are used only for optional comparison workflows.


7. Reproducibility Notes

The project includes explicit seed control through src.utils.reproducibility.set_global_seed, covering Python random, NumPy, and PyTorch when available.

Split generation is deterministic under the chosen seed. Evaluation JSON files also store the command line, seed, classifier settings, feature settings, split paths, runtime, and completion status so that result rows can be traced back to the exact run configuration.

For previously completed result files, check that JSON outputs report:

"completed": true

8. Optional External References

The core SGLT-RC pipeline is implemented in Python and does not require external MATLAB packages. Optional MATLAB-side comparison experiments are documented separately in external/README.md and use project-authored wrappers under external/project_wrappers/.

Submission boundary:

  • Submit: external/README.md and external/project_wrappers/
  • Do not submit as core code: local third-party folders such as external/sharingcode-LCKSVD/, external/face-recognition-using-DKSVD-master/, external/incrementallearning_LCKSVD_shared/, and external/spatialpyramidfeatures4caltech101/

Method references:

  • LC-KSVD: Jiang, Z., Lin, Z., & Davis, L. S. (2011). Learning a discriminative dictionary for sparse coding via label consistent K-SVD. CVPR. https://zhuolinumd.github.io/projectlcksvd.html
  • D-KSVD: Zhang, Q., & Li, B. (2010). Discriminative K-SVD for dictionary learning in face recognition. CVPR.
  • SRC: Wright, J., Yang, A. Y., Ganesh, A., Sastry, S. S., & Ma, Y. (2009). Robust face recognition via sparse representation. IEEE TPAMI.

About

Working codebase for SR-DGLTF: sparse-representation-based image classification with ResNet50 global features and LBP local texture features.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages