Close

Accurate scanning (unfortunately not...)

A project log for Super 8 film digitizer

Digitize old super 8 film reels

elbertElbert 07/13/2024 at 12:210 Comments

The frames have to be moved very accurately; the next frame should overlap at the precise place, otherwise the final film will not be stable.

The problem was that I have one stepper motor at the tooth wheel and one stepper motor on the reel that winds up the film. The reel that provides the film is rotating freely. The tooth wheel was after the microscope. So there was no tension between the providing reel and the tooth wheel. The frame did not uniformly move forward. This gave random positions in the photographed image and no way to make a stable clip. 

The proper design is to have the microscope between the tooth wheel and the receiving reel. In OpenScad I had to switch the tooth wheel and the microscope. And making sure that the screws did not interact with the other stuff. I had to make the base a little longer. 

Unfortunately, I did not succeed with this setup either. The tension on the film was not consistent enough resulting in an inaccuracy up to 20% of the frame. The tooth wheel and the sensor were too far apart. So I could not rely on the mechanical accuracy. Software has to come to the rescue. 

Instead of moving a complete frame, I let it move a third of a frame. The software will stitch these images together. A half frame movement would probably also work, but a third gives plenty of room for the stitching software. It is then very important to have equal lighting over the area of the frame, otherwise the light will jump from frame to frame. 

Although I usually program in C++, the easiest way (at least I thought) was to use Python with openCV in the PyCharm editor. The thing I really like about PyCharm is that you can install the packages with a few clicks. OpenCV has a stitcher function and there is even an example program in the openCV documentation. I had the stitcher running within an hour. Unfortunately, the stitcher could not stitch the images. Even the example images from the documentation did not want to stitch. A long internet search gave a few possible solutions, but it still did not want to stitch, without further information. Maybe is was Python or the PyCharm packages. So I used the pre-compiles OpenCV libraries with C++. Again, the same result. The stitcher did not want to stitch. 

So, there was nothing left then to write my own stitcher code. Which is not that difficult, but time consuming to get it right. I took a two step approach. First I stitch 4 images together. And then I search for the frame. The stitching is done by calculating the correlation between the two images with the latter shifted. The shift with the best correlation is then used. The correlation is simply the absolute difference of each of the red, green and blue value of the pixels. Having around 1 million pixels and 1000 possible shifts means to calculate 3 billion differences. But things can be done smarter. First we know that the frame has roughly moved a third of a frame. Secondly, we do not have to use all pixels, but can use a raster. This speeds up things a lot. 

Once the shifts are known we can combine the pictures. If we we we have a pixel in different images, we can use the average values. One can argue that this also gives a sharper image, but this is probably not the case. After we have a stitched image we search for the tell-tales of the frame: black lines between the frames and a white hole for the tooth wheel. This is also done by scanning the image and correlate with this frame tell-tale. We have to measure the exact positions of the lines and holes. I wrote also a function to improve these values by using a frame and see whether the correlation improves when changing the values of the black lines and the tooth wheel a little. 

This whole process is rather slow in Python, so I used C++. I also did not use OpenCV, but two simple jpeg libraries; Nanojpeg (actually the C++ version of Scott Graham) and Tinyjpeg (written by Sergio Gonzalez), and my own image class. 

Discussions