I use PGM image files a lot in my Engineering Computing class because the provide a really easy way for novice programmers to get started with image processing in C. This file format stores greyscale images in plain text and it’s easy to write C programs that write and read them using only standard library functions. It’s one of a closely related family of refreshingly understandable image file formats called Netpbm. Wikipedia provides a nice PGM example.
For quite a while, I’ve been meaning to create a lightweight DirectShow engine (a standalone executable) that allows C programmers to perform real-time machine vision simply by writing a program that reads and analyses a PGM file. RobotEyez is my first attempt at doing this.
When you run RobotEyez.exe, it opens a video capture device (e.g. webcam) and begins video capture (at the default frame rate and either the default resolution or the requested frame width and height). Individual frames are converted to greyscale and saved to a PGM file (called “frame.pgm”) or files (called "frame0001.pgm", "frame0002.pgm", "frame0003.pgm", etc) at a time interval specified by the user. The user can also specify a command to run after each image is saved. Command line arguments can be used to specify the capture device (by name or number), a delay before the first image is saved, the interval between subsequent saved frames, the total number of frames to save, the command to run after each file is saved, and whether or not a video preview window should be displayed during capture.
Download RobotEyez
The complete source code can be downloaded from the RobotEyes page on Github. If you just want the executable file, it can be downloaded from the following link:
RobotEyez.exe (44KB, 7-3-2012)
Another little program of mine called WatchPGM can be useful to run alongside RobotEyez. When you drag a PGM file into the WatchPGM window, it is displayed. What’s different (and very useful) about WatchPGM is that it keeps a close watch on the file, so that if another program (e.g. RobotEyez) modifies the PGM file on disk, the updated version is automatically displayed. Here’s the link to download the binary version of WatchPGM:
WatchPGM.exe (58KB, 28-11-2011)
RobotEyez Command Line Options
To specify the frame width and height:
/width IMAGE_WIDTH_IN_PIXELS
/height IMAGE_HEIGHT_IN_PIXELS
To specify a delay before first frame is saved to file (default value is 2000 milliseconds):
/delay DELAY_IN_MILLISECONDS
To specify the time interval between saved frame (default value is 1000 milliseconds):
/period PERIOD_IN_MILLISECONDS
To specify the total number of frames to capture to file (default value is 1; specifying a negative value results in indefinite capture):
/frames NUMBER_OF_FRAMES
To add numbering the saved image filenames (by default, the output filename is just "frame.pgm" – i.e. not numbered):
/number_files
To select a capture device by number (default value is 1):
/devnum DEVICE_NUMBER
To select a capture device by name:
/devname DEVICE_NAME
To list available video capture devices:
/devlist
To specify a command to run after each file is saved:
/command COMMAND_TO_RUN
To display a video preview window during capture (by default, no video window is displayed on screen during capture):
/preview
To save captured images as normal bitmap files (e.g. “frame.bmp”) rather than PGM:
/bmp
RobotEyez Example Commands
To capture a single image at 320×240 pixel resolution after a 1 second delay, and save to a bitmap file called "frame.bmp":
RobotEyez /delay 1000 /width 320 /height 240 /bmp
For example, to delay for 3 seconds, then capture ten frames at 1 second intervals from the default capture device to files called "frame0001.pgm", "frame0002.pgm", etc, while displaying the video preview window on screen:
RobotEyez /delay 3000 /period 1000 /frames 10 /number_frames /preview
To capture frames indefinitely at 0.5 second intervals to a file called "frame.pgm", calling a program called "imageproc.exe" after each frame is saved, use the following command:
RobotEyez /frames -1 /period 500 /command imageproc.exe
In the previous example, no video preview window is displayed on screen.
To capture an image from the webcam once every minute for 24 hours (1440 images in total) and save the files as "image0001.bmp", "image0002.bmp", "image0003.bmp", etc:
RobotEyez /frames 1440 /period 60000 /number_files /bmp

I’ve just added a “/bmp” command line option to save the captured images as bitmap format (“.bmp”) rather than PGM.
fantastic tool!
I stumbled upon it trying to get something working:
I bought 4 logitech c270 webcams and mounted them in 4 corners of my workshop. Now I want to capture images every 10 seconds or so and eventually render a time lapse video using virtualdub.
So far so good, I’m using 4 instances of RobotEyes in 4 separate directories.
I have 3 questions:
- is it possible to use the native webcam resolution (1280×720)?
- is it possible to start the 4 instances of RobotEyes at once?
- what happens when file # 10001 needs to be saved?
Any help would be greatly appreciated!
Kind regards,
Gabriël Zitman
Hi Gabriel,
Thanks for your message. I’m hoping to spend a day working on RobotEyez before I go back to work after the Christmas holidays, so hopefully I can look at the things you mention then.
Setting the resolution to 1280×720 shouldn’t be a problem, but it requires a recompile. I haven’t tried running more than one instance of RobotEyez and I can’t try it right now because I’m on a Linux machine right now. I might see about getting a single instance of RobotEyez to capture from multiple cameras simultaneously, which would probably be a better solution in the long run. I don’t know what happens when the image number gets to 10001 – I’ve never got anywhere close to that! However, I can change it to have a higher maximum value (i.e. more digits in the image number). What sort of maximum value do you think you might get up to?
Regards,
Ted
Hello Ted,
Thanks for your quick reply!
I’ve been working on my setup and I found out that running 4 instances simultaneously sometimes works, but most of the time doesn’t, due to CPU load. So your suggestion of one instance of Roboteyez capturing from multiple camera’s simultaneously (or alternately) sounds great.
The thing about reaching 10001+ is already solved by re-reading your documentation.
Have a nice new year’s eve,
Kind regards,
Gabriël
Hello Ted,
Did you by any chance have the luxury of spending some time on the roboteyez tool?
Any progress would still be greatly appreciated!
greetings,
Gabriël
Hi Gabriel,
Thanks for your message. Unfortunately, I’ve been pretty flat out at work for the last few weeks, so I haven’t had a chance to look at RobotEyez at all. I haven’t forgotten about it though. I’ll see if I can take a look at it later today.
I’m not sure if I have multiple cameras here (I certainly don’t have four), so if I do make any progress on capture from multiple cameras, I might need to ask you to help out with testing.
Regards,
Ted
Hi Ted,
Thanks for your reply, if I can help you with testing, just ask. No problem.
greetings,
Gabriël
Hi Gabriel,
Well, apologies for the delay. It turned out to be more difficult than I had anticipated to capture at a different resolution. However, I have just finally managed to get it working (at least on my camera). If RobotEyez is still on your radar at all, perhaps you’d be kind enough to give it a try to see if it works with your higher resolution cameras?
For example, to capture to a file called “image.bmp” at 1280×720 after a 2 second delay:
RobotEyez /delay 2000 /width 1280 /height 720 /bmp
I’m still planning to try to add simultaneous capture from multiple cameras, but I just got stuck on the variable resolution until now.
Works like a charm!!
Thanks Abhimanyu, I’m glad to hear it worked for you!
Great apps that you have wrote. I’ve been trying both commandcam and roboteyez. I like the ability to save the filename as a certain name in commandcam but like the resolution (or maybe ability to go higher) of roboteyez. Was wondering if you are able to change the resolution of commandcam to something different or set roboteyez to a certain filename? Also, is it possible to export the image as a jpg image so it isn’t so large per image (or have the ability to compress)? Would be highly interested in knowing if you can do these.
thank you,
Doug
Hi Doug,
I’ve just added a facility to change the resolution of the captured image – there are new /width and /height command line flags. It might be a while before I add flags to set the filename and/or output jpg files. However, if you install ImageMagick (open source, free to download and incredibly useful!), I think you’ll find that its “convert” command line utility will provide a very convenient way to convert the file “image.bmp” which has been captured by RobotEyez into “whatever.jpg”. I think it’s just something like:
convert image.bmp whatever.jpg
Sorry for the delay in replying. Hope this helps. Please let me know if it works for you or not.
Regards,
Ted
Hi-
This looks like a cool program, but I’m getting the msvcr100.dll is missing error. What version of Visual Studio did you use to compile this?
Thanks,
Kevin
I found the VS2010 redistributables at the link below. It is a cool program!
Thanks,
Kevin
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5555
Thanks for the comments Kevin. I don’t have my Windows laptop with me, so I can’t check the exact version of the compiler, but it was Visual C++ Express edition as far as I recall. It was definitely the free download version, since I haven’t paid for Visual Studio.
Anyway, I’m glad you got it working. I hope you find it useful!
Hi,
I like this program very much. However it doesn’t seem to be working to capture images of the resolution more than 640×480.
The highest resolution of my camera (Logitech C170) is 2592×1944. When I run it as RobotEyez /width 2592 /height 1944 /bmp, I am getting “Could not render preview video stream” error. How can I resolve this problem?
Look forward for your reply. Thank you very much.
Regards,
Ten
Hi Ten,
Thanks for your message. Are you ale to get RobotEyez working for resolutions smaller than 640×480? For example, can you please try:
I’m wondering whether the problem is with any size other than the default, or whether it’s just something to do with large image sizes. My Camera does not support high resolutions, so I haven’t had a chance to capture large images myself. With a bit of help from you, hopefully I’ll be able to solve your problem.
Regards,
Ted
Hi Ted,
Really appreciate your fast reply. Yes, RobotEyez works perfectly for the resolution smaller than 640×480 (for example 320×240). But it is not working for any size larger than 640×480. I am not sure what the problem is.
Thanks,
Ten
Hi Ten,
I looked up the specs for the Logitech C170 and it says it supports video capture up to 1024×768 (from http://www.logitech.com/en-gb/webcam-communications/webcams/devices/8113). RobotEyez opens the camera as a video capture device and then saves a single frame of the video stream as an image file. If the camera only supports higher resolution for still capture, unfortunately that may not work with RobotEyez, even though it is only capturing a still image.
Did you try capturing at 1024×768? I’m curious to know if that works.
Ted
Hi Ted,
It is not working for 1024×768 too. The error “Could not render preview video stream” occurred. By the way, is it possible to capture the picture in 640×480 and resize it to 2592×1944 by using another *.exe file?
I am sorry if I have troubled you.
Thanks,
Ten
Hi Ten,
No problem, no trouble at all! I’ll look into the problem to see if there’s anything in the code that might be preventing capture at higher resolutions. I can’t guarantee anything, but I’ll have a look.
In the meantime, there’s a good solution you can use to scale an image from 640×480 up to whatever size you want. There’s a very popular free and open source image processing toolkit called ImageMagick that provides a set of command line tools for doing all sorts of image manipulations.
Just google “ImageMagick resize” and you’ll probably find everything you need. ImageMagick is a really powerful package for automatic image processing so if you’re automating something to do with image capture and processing, you might find it useful for other things too. If you have any problems getting it working, let me know and I’ll try to suggest the right command to use (it’s probably the “convert” command you want to use, together with the right command line options). Unfortunately, if you capture at 640×480 and scale the image up, the quality won’t be perfect, but it’s worth a try.
Ted
Just a quick comment to say thanks for this very useful app – which also gave me the heads-up on PGM files too (much easier to process the image info for the task I’m doing).
Also I bumped into the same resolution problem as detailed above – though I actually sorted it by stopping being lazy, and supplying width *and* height options, i.e. if you supply one then the other becomes “required”, rather than imagemagick where you can of course just supply one dimension and the aspect ratio is retained.
Hi Mike. Thanks for the feedback. I’m delighted to hear you found it useful and that’s great that you got the resolution working. I should probably change that so that it’s possible to just specify the width or height.
Hi, Is there a way of recording a video? I have a requirement to record a short video clip triggered by an external event.
Thanks.
Hi Bruce,
I’m afraid video recording isn’t currently possible with RobotEyez. I have previously implemented a command-line video recorder that works similarly to RobotEyez, but it was commercial work rather than free software. Like everything else in DirectShow, recording to a video file (e.g. AVI) is surprisingly messy, but the code structure is similar in many ways to that used in RobotEyez. i.e. You create a capture graph containing a number of different DirectShow filters, then run the graph for as long as you want to capture video.
The source filter will be your camera. The sink filter will be an AVI file writer (or similar) and there’ll probably be one or two adapter filters in the middle. If you can get hold of Microsoft’s GraphEdit demonstration program, that will probably help to quickly identify the exact combination of filters you need in your graph. You can use it to construct a DirectShow graph graphically and try it out. Once you know what needs to be in the graph and how each filter needs to be configured, it’s much easier to put it together programatically.
Regards,
Ted
Thanks for all your work !
Just want to know if there is a simple way to convert the bmp outputed image to a jpg.
I use a batch that I call for every image captured, this batch look for all bmp files in the folder and convert it to a jpg with the convert command from ImageMagick. But I’m not happy about it cause I read and write in the same time.
Do you have any ideas ?
My batch :
RobotEyez /preview /delay 3000 /period %interval% /frames %nbFrames% /command %command% /number_files /bmp
command refer to my convert batch :
FOR %%F IN (*.bmp) DO (
convertto “.\%%~nxF” “.\%%~nF.jpg”
DEL %%F & echo converting to %%~nF.jpg
)
Hi White Sock,
Perhaps I’m not understanding your current method correctly, but it looks like you’re using one batch file to save a bunch of bmp files into a folder, and then using a second batch file to convert them all to jpg files one at a time, deleting each bmp file once you’re finished with it.
Am I right so far? If so, then I would suggest doing things slightly differently:
Does that sound like it would solve your problem?
Ted
Hi,
It is a very good job.
I tried RobotEyes on windows 7, on my notebook, and It worked fine.
But when I try it on my new tab,with windows 8, I have the message :
> Roboteyez.exe
…
copyright…
> Capture device : OV8830
Could not render preview video stream
Do you know if it is working with windows 8 ?
Thanks a lot for you good job
Hi Alain,
Sorry, but I don’t know if it runs on Windows 8 or not. Believe it or not, I’m still running Windows XP on my laptop, and I don’t have any computer running Windows 8 to try it on. If I get a chance to try it on someone’s Windows 8 machine, I will.
Ted