
I coded this project from scratch just using native C++ libraries (no OpenCV). There are several parts to this project, including:
For Canny Edge Detection, I took in a PPM image of the coins, converted it to grayscale, and applied Gaussian filters to smooth the image from noise. Using the Sobel Operator, I could then detect contrasting changes in the image signal, which usually meant an edge. However, there is still a lot of noise in the image, so I then used non-max suppression to remove the noise. Finally, I used hysteresis to remove the weak edges. Here is an example of my Canny Edge Detection output given an image:

I then needed to detect the circles in the image. I used the Hough Transform to detect the circles by drawing various radius circles at each pixel of an edge in the image. By accumulating the circles, I could detect which pixels represent the centroids of the circles, since they would have the highest intensity of overlap. I could then draw the circles on the image and detect the coins. Here is an example of the circles I detected in red:

Finally, by using a varying heuristic as well as the RGB value of the centroid pixel, I could then detect the different types of coins in the image and calculate the value of the coins. This is a robust way to detect coins in an image, even if there are overlaps and different sizes of coins. The result is shown at the top of this page.
Given a video stream, I used OpenCV to calibrate the camera using the chessboard, drawing the chessboard corners and orientation each frame. Due to the fact there is some distortion as well as there is occlusion of the chessboard, I used a 6 pyramid level optical flow algorithm to track the corners of the chessboard. I then used the optical flow to calculate the rotation of the chessboard and projected a cube onto the chessboard using a PnP solver.
I learned a lot about camera calibration, optical flow, and PnP solvers through this project, especially how we can use historical data to fill in missing data in the current frame.