Overview: NumArt is an end-to-end system that transforms a user’s uploaded image into a printable paint-by-numbers kit and, optionally, dispenses the required paint colors using a hardware mixer. The software pipeline handles color quantization, segmentation, and vectorization to produce a clean, scalable SVG output, while the hardware setup uses Raspberry Pi–controlled peristaltic pumps to mix and dispense paint according to the generated palette. The project combines computer vision, clustering algorithms, and embedded systems for a full digital-to-physical creative workflow.
Key Features:
Image Quantization: Uses K-Means clustering (via scikit-learn) to reduce an input image to k representative colors. Each pixel is assigned to the nearest cluster centroid, creating a simplified color palette ideal for painting.
Label Map Generation: The quantized image is converted into a 2D label map, where each pixel corresponds to its color index. This map is cleaned using majority filters and region-merging algorithms to remove noise and ensure paintable areas.
Vectorization & SVG Export: The cleaned label map is converted into vector paths, with each region assigned a number and lightly filled for visibility. The final SVG includes a color legend and can be printed directly as a paint-by-numbers template.
Hardware Integration: A Raspberry Pi 4 controls five 12V peristaltic pumps connected to color reservoirs (Red, Green, Blue, White, Black). The pumps precisely dispense paint volumes to recreate the digital palette physically.
Python Driver & FastAPI Backend: A Python FastAPI service coordinates the process—from receiving an image upload to processing it through the quantization pipeline and sending dosing instructions to the Pi for paint mixing. The Modbus or GPIO driver handles real-time pump control and calibration.
Physical Assembly: Pumps are mounted in an enclosure and connected via silicone tubing to color reservoirs and a magnetic stirrer. The Raspberry Pi, relay board, and 12V PSU are wired with shared ground and secured for safety and reliability.
Technology Used: Python 3.12, FastAPI, NumPy, Pillow, scikit-learn (K-Means), OpenCV, svgwrite, Raspberry Pi 4, peristaltic pumps, relay modules, and 12V DC power electronics.
Process: The project begins with image validation and downsizing before applying K-Means to extract dominant colors. The palette and label map are refined with region cleanup and distance transforms to ensure each zone is large enough to paint. The resulting vector outlines are exported as a numbered SVG. In parallel, the Raspberry Pi interprets the same palette and activates each pump for a calibrated duration to produce corresponding paint mixtures in small beakers with magnetic stirrers. The system can handle up to five base colors and generate custom blends automatically.
Challenges: Achieving clean segmentation for complex images, balancing speed versus accuracy in K-Means clustering, preventing color bleeding between small regions, and synchronizing hardware control for consistent dosing were key engineering hurdles. Additionally, ensuring repeatable pump calibration and stable power distribution on the Pi relay circuit required careful tuning and testing.
Overview: This project involved the design and implementation of a custom RISC-style processor with 8 general-purpose registers and a compact instruction set architecture. The goal was to build a minimal yet functional CPU capable of executing arithmetic, logic, and branch instructions, including support for 16-bit integer and 16-bit IEEE-754 floating-point data conversions and addition/subtraction. We used the processor's custom instruction set to write a program in Assembly Language to handle the conversion and computations. A custom compiler for the instruction set, to convert the program from ASM to machine code was also created using C++.
Key Features:
Register-register / Load-store architecture with direct and indirect addressing
Optimized register file design, prioritizing registers 0 to 3 for frequently accessed operations, while 4 to 7 are utilized for storage. Special handling of 0 as the implied destination for certain branch comparisons.
LUT-based conditional branching and control flow, storing up to 32 jump locations
Custom instructions for logical shifts, bit manipulation, and subroutine handling
Logical shifts can span one or two registers.
Support for 16-bit integer and 16-bit IEEE-754 floating-point data types
8-bit wide, 256-byte deep memory, to support indirect addressing during memory access instructions
The ALU also supports a comparison operation. Given two registers (R0 and R1), it will compare the data in these registers and return one of three values..
Control unit to decode the instruction code (op-code) and manage the flow of data across the data path.
Process: The processor architecture was designed from the ground up, starting with the instruction set and register file. An ALU module was built to support both standard arithmetic and custom bitwise operations. A memory subsystem handled instruction and data memory independently. Testing was performed with custom testbenches and waveform outputs to validate correctness at each stage.
Challenges: Addressing edge cases in floating-point conversion, handling operand ordering in memory instructions, and eliminating infinite loop scenarios in early branch logic prototypes.
Overview: PokéCollect is a full-stack, component-based web application that enables users to browse, collect, and organize Pokémon cards from all generations. Designed for TCG collectors, the app supports real-time data integration, responsive UI, and persistent offline access using progressive web app (PWA) features.
Key Features:
Dynamic card search and retrieval with high-quality metadata (HP, rarity, set, pricing)
Stateful collection management and binder customization by clicking to assign cards to specific slots
Service workers and API fallback for robust offline functionality
Modular design with reusable Web Components and clean separation of concerns
Fully integrated CI/CD pipeline with GitHub Actions for build, test, and deployment automation
Unit testing (Jest), static analysis (Codacy), linting (ESLint), and >70% code coverage enforcement
Technology Stack: HTML5, CSS3, JavaScript (ES6+), Web Components, GitHub Actions, Jest, ESLint, Codacy, Service Workers, Pokémon TCG API
Development Process: Followed Agile methodologies with sprint planning, issue tracking, code reviews, and iterative delivery through GitHub Projects and pull requests.
Challenges: Managing state across dynamic components, ensuring consistent data synchronization between frontend and API layers, and maintaining high code quality through continuous integration workflows.
Accomplishments: Deployed a production-ready, mobile-responsive web application with a scalable architecture, developer-friendly tooling, and seamless user experience tailored to the TCG community.