Shan Kanwar

Mechanical engineering at NYU Tandon, with a finance minor. I build things that replace expensive hardware with cheaper hardware and better software — and I like the part of the problem where you have to prove the cheap version actually works.

2026NYU Tandon, General EngineeringPhysical Design Lead

VTAB — a $16 drawing tablet with no tablet

A pen that turns a phone camera and a gyroscope into a graphics tablet, at roughly a third of the cost of the cheapest commercial one.

Problem

Almost every tool a digital artist needs has a free or cheap version. The drawing tablet doesn’t. Commercial tablets sense the pen with dedicated hardware — a grid of electromagnetic-resonance coils or pressure sensors buried in a rigid slab — and that slab is most of what you’re paying for. It also makes the thing bulky. Even entry-level models start around $30–$40, which is a real barrier for someone who just wants to try drawing digitally.

Approach

We deleted the slab. Position comes from a phone camera watching a strip of blue tape on the pen tip; orientation comes from a 9-axis gyroscope riding inside the pen next to an Arduino Nano. A Python and OpenCV pipeline fuses the two streams into a live coordinate, pipes it into a C++ interface, and that interface drives a custom Windows HID driver over IOCTL calls so the pen moves the actual system cursor — not a drawing in a demo window. With no pressure switch in the tip, the space bar became pen-up / pen-down.

I led the physical design: modeling the pen in Fusion 360, packaging the Nano and the gyroscope inside a body a hand can still hold, and iterating the print until everything fit.

Result

The prototype writes legibly. Side by side against a Wacom Intuos, the strokes are shakier but unmistakably the same letters — which was the whole question. Total bill of materials came to $16.02 against about $40 for the closest commercial tablet.

It is not finished. The internals are still too big, so the pen is two to three times the diameter of a normal one; it needs a wired connection; and gyroscope drift degrades tracking over long strokes. Sensor fusion with an accelerometer and a smaller microcontroller are the next two fixes.

Build

Sensing
9-axis gyroscope, phone camera, color-target tip tracking
Compute
Arduino Nano → serial → Python / OpenCV → C++ → Windows HID driver
Driver
Microsoft vhidmini2 base, WDK, built in a Windows 11 VM, WinDbg over COM
Physical
Fusion 360, 3D-printed housing
Cost
$16.02 total — $5.33 Nano, $9.99 gyroscope, $0.70 misc
The word VTAB handwritten twice: once by the VTAB prototype, once by a Wacom Intuos tablet.
Fig. 1   The same word written by the prototype (top) and by a commercial Wacom Intuos tablet (bottom).
Flowchart: phone camera video and pen gyroscope feed a Python pen-detection process, which pipes coordinates to a C plus plus driver interface, which sends IOCTL updates to the kernel driver.
Fig. 2   Two input streams, one cursor. Camera and gyroscope are reconciled in Python, then handed down to the kernel driver.
Isometric CAD section view of the pen showing the Arduino and gyroscope packaged inside the barrel.
Fig. 3   Section view of the pen body.

2024NOAA Ocean Exploration Video Challenge2nd place, team of four

Counting brittle stars on the seafloor

A computer-vision model that finds every brittle star in ROV footage, frame by frame, so marine biologists don’t have to count them by hand.

Problem

Brittle stars build their skeletons out of calcium carbonate, which dissolves as the ocean acidifies — that makes their population a direct readout on how much carbon the water is absorbing. Reading it means counting them, and counting them today means a researcher scrubbing through hours of dim, noisy, bottom-facing ROV video and tallying by eye. NOAA and the MATE ROV Competition put the problem to students: build something that keeps a box on every animal through the whole clip.

Prior work on brittle-star detection existed, but only for tightly localized survey sites. We wanted a model that held up across a habitat range.

Approach

We pulled 2,606 labeled images of Ophiuroidea from FathomNet — MBARI survey imagery plus community-verified submissions — spanning the East and Indo-Pacific, the U.S. and Mexican west coast, and the waters around Hawaii. Another 412 images of starfish and glass sponges came with them; we cut those, because a handful of minority classes drags the model’s predictions around more than it teaches it anything.

Deep-sea video is a hostile input — green cast, particulate snow, animals that blur into sediment. So we augmented hard: six Albumentations transforms, four that perturb pixels (Gaussian noise, blur, gamma, hue/saturation) and two that move the subject (vertical flip, rotation), applied probabilistically so no two training passes looked alike.

For the detector we used YOLO, which scores an entire frame in a single pass instead of proposing regions and re-checking each one — the difference between something that can keep up with video and something that can’t. We fine-tuned YOLOv7, v8 and v9 across 2, 10, 50 and 100 epochs on a rented A100 to see where each one stopped improving.

Result

0.712 mAP at 0.5 IoU, with performance flattening after about 50 epochs. The interesting finding was which model we shipped: not the most confident one. YOLOv7 at 50 epochs drew tighter, more certain boxes, but YOLOv7 at 10 epochs was less cautious and therefore caught more of the faint, half-buried animals. Since the deliverable is a count, we took the model that finds the most real stars over the one that is surest about fewer.

Everything struggled on organisms drifting well above the seabed, where the outline dissolves into noise. We handed NOAA and MATE ROV an annotated evaluation video plus a spreadsheet logging every detected star in every frame — the tabular log a biologist actually needs. Second place.

Build

Data
2,606 FathomNet images (MBARI + citizen-verified), 412 off-class removed
Augmentation
Albumentations — 4 pixel-level, 2 spatial transforms
Models
YOLOv7 / v8 / v9, fine-tuned at 2, 10, 50, 100 epochs
Metrics
mAP @ 0.5 IoU, precision, recall
Compute
NVIDIA A100 40GB in Colab — about 2.5 min per epoch, 30GB in use
Three frames of seafloor video with orange bounding boxes labeled Ophiuroidea, showing progressively more detections as training epochs increase from 2 to 10 to 100.
Fig. 4   The same frame of NOAA ROV footage scored by models trained for 2, 10 and 100 epochs. More training tightens the boxes; it doesn’t always find more animals.

JavaAlgorithmsPersonal project

FinanceSorter

An expense analyzer built to answer a question textbooks usually skip: when is the slow sorting algorithm the right one?

Problem

Insertion sort is normally taught as the algorithm you learn and then discard — O(n²), beaten by everything. That framing hides its actual property: it is adaptive. On data that is already close to sorted it does almost no work, and a great deal of real data — a bank statement, a log file, an append-only ledger — arrives close to sorted. I wanted a tool where that claim could be measured instead of asserted.

Approach

A single-file command-line program in Java, built around a generic insertion sort that takes any List<T> and a Comparator. One implementation therefore orders transactions by amount, by date or by category, and it counts its own shifts and comparisons and times itself — so the cost of the sort is visible next to the result, not hidden behind it.

Around that: a CSV reader that handles quoted fields with commas inside them, a fallback generator that invents a realistic ledger if you don’t hand it a file, a sorted CSV written back out, and a spending report — total, average, largest and smallest expense, spend by category as a text bar chart, top five expenses. A self-test suite covering sorting, edge cases and CSV round-tripping runs on every launch, because a tool that reports numbers should verify itself before you believe them.

Result

The built-in benchmark runs insertion sort against Java’s own Collections.sort on the same 401-row ledger, once nearly sorted and once shuffled. Nearly sorted: 423 shifts. Shuffled: roughly 41,000. Two orders of magnitude, same data, same code — which is the answer to the question, and a far more useful thing to know than the worst-case bound on its own.

Build

Language
Java, single file, no dependencies
Core
Generic insertion sort over List<T> with Comparator
I/O
CSV in and out — date, description, category, amount
Instrumented
Shift count, comparison count, wall time per sort
Verified
Self-test suite on every launch