Any CS-mount camera deserves autofocus!
I have been working on open-sourced motorized zoom lens for a while. Probably there is no need to mention benefits of having motorized zoom/focus lens on a regular CS type camera. Even greater value comes by having auto-focus capability. This feature is being calculated on host computer and does not consume lot of resources. Many other features can be added to suit particular needs (like automated object fitting into frame, barcode scanning, etc.).
I have also been interested in computer vision algorithms and frameworks for a quite a long time. Naturally I have chosen OpenCV (which is kind of De Facto for most research applications).
As I later found out it is not so difficult to calculate useful analytical data by yourself. Contrast (or inverted blur) ratio can be found by calculating Laplacian transformation. Which is pretty fast to work in real-time.
For a while I could not decide which microcontroller to use, there are so many families to chose from. Benefits of attracting Arduino community made me taking the a risk and I chose Atmega328p. So motorized lens controller is based on popular Arduino platform. While redesigning to another base is not as hard as making project from scratch, probably I will stay with current design for a while.
At the beginning had intentions to use grbl but as I found out it was not quite suitable for this application. While being perfect for 3D printers, cheap laser engravers and small cnc Routers, it is difficult to make necessary adjustments (uses one port for all STEP pins, it is difficult to split. Due to PCB routing decisions I placed STEP1 and STEP2 on PORTB and PORTD. Uses GPIO pins to control motor direction, my controller has to send special SPI command to change direction. Also lot of functionality needed to be stripped and necessary to be added).
Full source code (Python and Arduino) of working code is located on Github. Feel free to use and modify according to your needs.
Current firmware version provides these features:
- G-code like commands
- Simultaneous movement of both axis
- Possibility to stop motion at any time (M0 code)
- Set current coordinate as (G92 X.. Y..)
- Set timer register (in general motor speed)
- Set coil power
- Coil power is automatically lowered after motor is stopped moving
- Real-time position (and some other parameters) reporting to host
- Basic auto-focus functionality
Single package solution makes lens controller move, captures frames from USB camera and analyzes frames to detect best global focus. All tools under one hood.
Notes and thoughts
- Time to shift from focus 0 to focus infinity takes ~4 seconds. It might be boosted to ~3seconds by increasing stepping frequency and motor coil current.
- It takes ~15seconds to fully focus from unknown state without any optimizations. This is dumb method of finding best focus. Normally there should be smarter adjustments without moving lens full range.
- To speed up operation various additional components can be used:
- Controller has ADC in pin located on unpopulated header it is possible to add infrared distance meter. Distance would be reported to software and it will be much faster to lock focus.
- Laser pointer also can be used to triangulate distance to visible object. Drawback – there would be some lost frames due to visible red spot, but in photo mode this could be perfectly suitable.
- Focusing algorithm can be written to measure if blur rate is getting increasing or decreasing. If going wrong direction seek focus would be reversed to save time.
- Adding presets might be nice touch to demo program.
- ROI (Region Of Interest) can be added to focus on subject of interest.
- Notes about lens:
- Lens can focus from 0mm to infinity.
- Focal length can be changed from 2.8mm to 12mm.
- Try on Raspberry Pi headless mode. It should be enough of power to handle control and focus algorithms.