Monday, June 6, 2011

Acquiring images from an Analog Camera using Arduino

Incredible but true, I managed to acquire images from an analog camera using an Arduino!!!! I had the inestimable help of Mike from Nootropic Design, who helped me modifying hardware and software from the video experimenter shield.


If you are interested (I bet you are) you will get the chance of doing it yourself because I am giving all the code so that you can do that at home (at your lab or for your favorite robot!!).

Feel free to skip the sections you want to skip, but I though a little bit of background is important for the whole understanding of the project.

Introduction
 This project is based on the video experimenter shield by nootropic design. The idea behind this project is to be able to capture images from an Analog Video source and send them to a computer.
Big challenges
- Memory limitation on the Arduino
- Speed (perfomance) of the 8 bit microcontroller
- Dynamically changing the threshold on the board.

Limitations
 - The images acquired are low  resolution (128*96)
- The bit depth is adjustable. BUT THERE IS A TRADEOFF... the higher the bit depth the longer it takes to take an image.
- MONOCHROME ONLY no color.
- The code provided acquires images of 3 bits depth (8 levels). Getting more levels is pretty straighforward.
- The code is provided as is, you can use it as long as you quote me on your sources/publications. You can also contact MoviMED to get my 'professional'  services (not for free).
- For the time being the PC side is coded in LabVIEW (easiest option I had available). A Processing code is on the way.

Concept
The idea behind this project was to modify the assembly code provided by Nootropic Design to
- Send thresholded images back to a PC via serial
- Dynamically change the threshold so that different thresholds give different images that can be reassembled back in the computer. That is because the arduino does not have memory enough to store more than one thresholded image.
- Initially the idea was to software control the threshold but the wise advise from Mike led me to use an external DAC (resistor ladder) to externally force thresholds.


This means that the code does the following
- Wait for a serial character to trigger the acquisition
- Set the threshold for an image
- Acquire that image
- Re set the threshold for another level and iterate
- Once all levels have been acquired (8 in the example) idle


The counter part (PC)
- Sends a character
- Waits for the images to come
- Reconstructs the image



The images
Here are some images of the  MoviMED crew (me, John, Jesi and Dave) so that you can see the kind of resolution and bit depth images you can achieve. See below












What do you need?
 Here is the list
- Arduino - I used the uno, it should work on the diecimila but my diecimila does not like it. My board is old (2006) though. Might try it though. It will not work on the Mega, see why.
- Video Experimenter Shield -  I do not work for Nootropic Design but I recommend you buying this because it will open up lots of possibilities for your Arduino projects!!!
- 1% Resistors - Yes 1% is important. I used 95.38K resistors but any value should do. It is relevant that they are acurate for the kind of conversion needed.
- A potentiometer -  The value should be in the ballpark of the resistors mentioned above.

Hardware Rig
Here is a picture of the eagle schematic of what you need to assemble on top of the video experimenter shield

You can also download this image and the eagle schematic from this link. See comments on the file behind the link below.

Arduino Code and LabVIEW counterpart
Find all the code you need to run this in the same link as before. Some comments on that though

LabVIEW front panel of the image acquisition

LabVIEW code


- The code is provided as is. No guarantees and I will not support it, but I can provably give you some guidelines.
- Performance - It takes about 1 second to acquire an image, so 8 level images take about 8 seconds. I can get it better by packing more info per serial packet (I am only sending a bit per byte). I will do that when I get some extra time. So far I wanted to prove the concept.
- I am planning to code the same thing in Processing. I do not program in processing but I know several other languages so I guess it is not going to take long. 
- The LabVIEW code requires LabVIEW 2009 and NI Vision.
- Thanks Mike for your help!!!

Where to go from here

Personally I am going to work on the processing side of things so that this code is useful for the none labview guys too. 
Adding more levels should be straight forward. But keep in mind, more levels, more time to acquire an image. If you move while acquiring you might get funny pics.

Great projects from here (I am already planning to do them, I will post the results here, let me know if you get there before I do).
- Store your images in a flash chip (from microchip for instance).
- Store your images in a SD card
- Do image processing, such as filters, line profiles, edge detection, etc with multi level images
- Make your little pan and tild track an object based on vision.
- Get a Maple from LeafLabs to acquire a multilevel image (major project).
- Other


Thanks
-Thanks to Mike from Nootropic Design for the help on the technical side of things
-Thanks to MoviMED, I used the cameras from work to test this code out. Check out our website and consider our AF-150x for your next RIO project!!! Consider us for any Machine Vision project!!


5 comments:

  1. Colour ought to be easy enough, harvest a colour wheel from a broken DLP projector and synchronise it to the frame rate of your camera.

    Also means higher resolution as no patterned colour filter needed.

    I did consider using a cheap digital picture frame screen as a switched filter but this approach loses too much information and results in low contrast.

    ReplyDelete
  2. This is a great idea and awesome that you pulled it off. You may want to check out the LabVIEW Interface for Arduino (LIFA) at www.ni.com/arduino. It takes care of all of the LabVIEW to Arduino serial communication and its all open source and free. It even allows communication via Xbee or Bluetooth. If nothing else it might give you some ideas for implementing communication between LV and the Arduino. It would be cool to see you integrate this with LIFA. If you plan on working with LIFA post on the community forum (also at www.ni.com/arduino) and we'd be happy to help you integrate this with the toolkit.

    Keep tinkering,

    -Sam
    LIFA Developer

    ReplyDelete
  3. Hi Carlos, just found your blog looking for image processing with Arduino.
    Excellent work, congrats. I hope you still receive the comments.
    Maybe you can help me. I am looking for some image processing with Arduino (or other platform like Maple) but with colors. However, the resolution could be much lower (16x16, for instance) and I don't need to have the entire image at once neither store it: I just have to trigger some external circuit based on the color of the pixel. For instance: if the pixel at position [1:1] on screen is green, then set output 1 to HIGH. This processing is done sequentialy, for each pixel of interest in my project.
    Do you think this is possible?
    Thanks in advance.
    Regards
    Luis

    ReplyDelete
    Replies
    1. Hi Shadow,

      Thanks for the comment on the post and the different emails. So color is a little bit difficult as it is encoded as phase changes on the AV (NTSC or PAL) signal. This means that you cannot use the board from nootropic to do the color trick as the board takes advantage of the analog acquisition from the arduino based on the timing separator.

      There are different alternatives
      a) Color wheel + servo. This is an old school trick that might work in your case. Acquire 3 images with three different color wheels in front of the camera and recompose the RGB image.
      b) Using an AV acquisition chip. That one I disrecommend as those chips typically have high frequency output (27MHz) not handled by low performing micros.

      Hope it helps!!!

      Carlos

      Delete
  4. I connected Arduino, Nootropic video shield and the resistor ladder. I loaded both codes and I saw the black and white image on TV, adjusted with the pot. But the Processing screen is all black. What must be done?

    ReplyDelete