Defining what similar means
This project felt freestyle. The course defined the required features, but we still had to research different approaches, decide how similarity should be represented, and keep adjusting the system until it worked across a large image collection.
Imagine rotating one image by 90 degrees. It contains the same colors and subject, but its spatial structure changes. If rotation should not matter, a global color histogram may be useful. If orientation and local patterns should matter, texture becomes more useful. Neither method was universally better because the correct choice depended on what the user meant by similar.
The project felt unusually academic because every result came from mathematics we implemented ourselves. Color became an HSV histogram, texture became features extracted from a grey-level co-occurrence matrix, and cosine similarity ranked the resulting vectors.
There was no neural network, pretrained embedding, or external recognition service. It surprised me how far plain mathematics could go and made every result traceable to a calculation we understood.
Connecting the complete system
I preferred working across the whole application rather than owning one isolated component. My teammates focused primarily on color and texture extraction. I contributed to the algorithmic work, built the Flask API, and connected everything to the Next.js interface.
Integration required more than exposing an endpoint. Once we tested the complete experience, I adjusted processing, uploads, parallel execution, and caching so the application remained usable. Our collaboration was straightforward and worked very well.
Early versions felt acceptable with small folders. Performance became a serious problem when we used the complete dataset containing thousands of images. Every image had to be loaded, converted into features, and compared with the query.
We introduced multiprocessing so extraction could use multiple CPU cores, then cached dataset vectors in CSV files. Later searches only needed to extract the new query image unless the dataset changed.
When a white lion becomes a white cat
We had to choose how colors were grouped, which texture relationships mattered, and what score was strong enough to display. We selected the 60 percent cutoff through testing rather than a universal rule.
The formulas could be correct while the results still felt wrong. Processing time and the heuristics around edge cases became the hardest parts of the project.
A white lion could rank close to a white cat because their overall color distributions were similar. The system did not understand the subjects. It only understood the features we chose to measure.
The system always answered the mathematical question we gave it, even when that question differed from what a person intuitively expected. Those failures often explained the algorithms better than the successes.
Mathematics as an engineering tool
We implemented the course's bonus features to explore the engine beyond a single upload. Users could scrape a website into a dataset, search with webcam frames, and export ranked results to PDF.
These additions made the project feel complete, but also exposed more integration and performance problems. An algorithm becomes a different engineering challenge when it must accept folders, cameras, websites, and thousands of files.
If I rebuilt the project, I would optimize the existing pipeline, improve feature extraction, and compare it with modern image embeddings. The goal would be to understand what a learned representation improves and what it makes harder to explain.
The project showed me that useful image search does not begin with artificial intelligence. Plain mathematics can already produce meaningful behavior. It also showed me where that mathematics stops.
What stayed with me
- Similarity is a definition before it is a calculation.
- Plain mathematics can go surprisingly far without a trained model.
- A white lion can look like a white cat when color is all you measure.
- Scale changes an algorithm into an engineering problem.
Run it locally
Clone the source repository or download the project ZIP, then run these commands from the project folder.
Explore the complete project
Download the source, assets, and included documentation as a ZIP archive.
Backend
$ cd src
$ python3 -m venv .venv && source .venv/bin/activate
$ pip install -r ../requirements.txt
$ python index.py
# http://127.0.0.1:5000
Frontend (second terminal)
$ cd src
$ npm install
$ npm run dev
# open http://localhost:3000, then Upload Folder (try test/animal),
# Upload Photo for the query, toggle Color/Texture and Search
# This download keeps test/animal and test/fruit as ready-made datasets;
# the two largest corpora were trimmed. See test/SAMPLE.md.




