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:

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:

RobotEyez Command Line Options

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:

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?

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.

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.

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.

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.

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.

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.

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:

RobotEyez /delay 3000 /width 320 /height 240 /bmp

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

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.

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.

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.

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.

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.

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.

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.

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:

I would just use a single batch file, which would repeatedly snap an image using CommandCam or RobotEyez.

The same filename would be used every time – e.g. “image.bmp”.

Each image would immediately be converted to jpg using ImageMagick.

You could use the date command to give each jpg filename a different filename; for example, as shown here.

There would only every be one bmp file (“image.bmp”) in the directory. It would be overwritten each time a new image is snapped.

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.

Thanks you for you work ! it’s a great apps but I have a probleme with it. I can take snapshot with my old laptop (windows 7 32bits) with a capture at 1280×720 but when I try to take a snap shot with my new laptop (windows 7 64bits), It doesn’t work…(“Could not render preview video stream”) But with a fewer resolution (640×480), I have no problem.
I think the problem is the version of windows (32 or 64) but I am not sure. Do you think is that or there is an other problem ?

Are you using a built-in camera in each laptop. In other words, are you using two different cameras. Each camera manufacturer provides hardware and software drivers that support a specific range of resolutions. Could you try to confirm using a different program whether the new laptop’s camera is capable of video capture at 1280×720? You could try using something like VLC to check it.

I use the same camera in each laptop. It’s an external camera “microsoft lifecam studio” and i can take picture in 1280×720 with it. It’s also possible to take picture in 720p with the new laptop with an other software (VLC and the microsoft lifecam studio software) but not with your application

I am also new to this (isn’t that a pre-req statement for posting?), and have been enjoying playing around with your application. I am running off Windows 8.1 tablet and got the default lower resolution to work. when I try and enter in 1280×720 (or any other arguments) I get the “could not render preview video stream” error. I am looking through the source code, but I am 15 years out of practice on this and can not discern the error. Any ideas?
btw, great job on this and the CommandCam program!

I think I am starting to understand what is happening. the camera/computer can’t generate a preview stream at the high resolution, so kicks out and doesn’t take the high res picture. that said… is it possible to not use the preview stream and just allow the high resolution picture?

Hi Scott. Thanks for your messages. Unfortunately, it’s been a while since I looked at this, so I’m struggling to spot the problem. Also, I don’t have any Windows PC at the moment to test this on, let alone Windows 8.1, so I’m quite limited in what I can even investigate.

When you say “is it possible to not use the preview stream”, wouldn’t that just be the same as not specifying the “/preview” option on your command line. In the program’s source code at line 116, you’ll find the following…

Either way it looks like you’re connecting to the “capture” pin of the device, and you’re either letting DirectShow open a preview window, or else your telling it to use the null renderer which is basically a dummy output device that displays nothing.

Thank you so much for making such an awesome program. I had started to make one of my own using Python and came across RobotEyez on a lucky search I was doing. This has saved me so much time. Right now it pretty much does everything I want it to. I am super happy that it does not take a picture with the WebCam, but captures a frame of the feed, as this particular camera has poor quality pictures but 1080p video (weird but oh well).

I have been looking through the source code, but am not super comfortable with cpp. Is there a way to change the directory that the file is saved in? I can use cmd or a batch file to rename the file, but I need to be able to dynamically change the directory ideally, or at least be able to set the default directory.

At the moment I am using the /command to relocate the file, but when I migrate this to the desired system, I would need the file saved to a different location than the running location as I will not be able to change the directory it will be run from.

Hi Ted,
Very impressed with CommandCam, and I have that working on a Windows 8 tablet – but I can’t seem to get RobotEyez running.
I am after higher resolution photos of course 🙂 CommandCam defaults only to 448×252.

I get the “Could not render preview video stream” error, regardless of what resolution and other settings I experiment with.

I understand you may not be able to test with Win 8 – but I am working on the assumption that as CommandCam works then Roboteyez should also? Would you have any suggestions to get this working?
The camera is IMX175 as reported before the error, built-in rear-facing camera on an Asus tablet.

I was very excited when I found this, and I’m really hoping to have success with it. I will be more than happy to make a donation if I can get it running.

Sorry, but I’m up to my eyes at the moment, so I haven’t had time to investigate your problem at all. To be honest, I haven’t tested RobotEyez in Windows 8 at all, so your problem could be related to that. Both RobotEyez and CommandCam access the camera using Microsoft’s DirectShow API, but they do so in slightly different ways (using different DirectShow filters, which are the virtual objects you connect together to set up and carry out a video capture operation in DirectShow) so there’s no guarantee that RobotEyez will work just because CommandCam does. That said, some people here seem to have had at least some success running RobotEyez on Windows 8, so hopefully it is possible.

Anyway, sorry but I just don’t have time to get to the bottom of it right now due to heavy workload at the end of term! Best of luck finding a solution.

Sorry for the delay in responding. I’m up to my eyes at the moment and I’m afraid I can’t work out exactly why you’re getting those errors. I haven’t really tested RobotEyez at all in Windows 8, so it’s quite possible that it’s a compatibility issue related to the operating system version.

I wish I could spend a bit of time getting to the bottom of this, but I’m afraid it’s just not possible at the moment due to work commitments. Sorry I can’t be of more assistance!

Unfortunately, RobotEyez doesn’t provide a feature to list a camera’s supported resolutions. However, you could probably use another application to get the list. I’ve used Microsoft’s GraphEdit program to do this in the past:

I created a batch for your tools to take some pictures via webcams .This pictures i´m using for Product Photography. And I wanted you to ask, is it a problem to you if i use this Pictures on a onlineshop to sell the products?

Regarding your query: As long as you’re only using the actual photos that you took with RobotEyez for commercial purposes, then that’s no problem whatsoever. Any photos you take with RobotEyez are 100% your own property and you can use them without any more restrictions than if you had taken them with your own camera. However, it’s different if someone wants to incorporate RobotEyez (the software itself) into a commercial product. That would be more complicated.

I don’t think I’ve actually stated it above, but I’m happy to make RobotEyez available under a GPL type license.

Ted,
I would like to reference you and your software in a presentation to the polymer testing industry. I use this software regularly to capture periodic images of samples in physical tests. I would like to present my method which incorporates your software. Please let me know if this is O.K.

As you’ll see in the Makefile in the github repo, I used cl.exe (the microsoft C/C++ compiler that Visual C++ is based on) to compile RobotEyez. For most C programming, I use gcc (from MinGW when I’m in Windows), but that can’t be used for this because RobotEyez uses DirectShow, which seems to require Visual C++ (or cl.exe). You can download cl.exe for free from Microsoft. I think it was in the platform SDK download or something like that when I last installed it, but that’s going back a few years now, so the details are hazy!

Anyway, the short answer is that it’s probably not possible to compile DirectShow applications (including RobotEyez) in Cygwin. Sorry.

Hi,
I have been using CommandCam for some time without issues but since “upgrading” to Windows 10 the preview function has stopped working. I am currently testing RobotEyez calling from Excel VBA but for some reason the default location is C:\Users\\Documents.

RobotEyez should just save the captured image file in the current working directory. If you’re running RobotEyez from a VBA program, you should be able to just set the current directory to whatever location you want before you run RobotEyez.

I think there’s a function you have access to in VBA called SetCurrentDirectory or something like that. Hopefully it will do what you need.

Hey Ted,
Just wanna say, superb job on making this program! I find it incredibly versatile and so inconspicuous when run! The fact that I couldn’t actually set a file name was annoying, but I have managed to fix that problem using a batch file. So to those of you out there who also have this issue, here’s the code that I made (note, this is in a batch file so .bat):

cd *program location"
RobotEyez /width 1280 /height 720 /bmp

^ Activating RobotEyez.

for /f "tokens=1-8 delims=::./" %%A in ('echo %DATE% %TIME%') do set FileDateTime=%%A-%%B-%%C.%%D.%%E

^ Create a variable that will later become the name of the photo. I chose the date and time because this was the most practical and also it’s unique for every photo so no overriding XD.

ren "frame.bmp" "Taken on %FileDateTime% Local Time.bmp"

^ Change the default file name into the unique time-based name.

I know this code is really quite simple, but I have only started to program this year and so it took me a good half-a-day to complete. Hope someone out there will find this useful.

Hi guys,
is there any way to take a picture in ANY resolution given in parameters e.g. 100×100? what is more i’m courious if i can save the pic in B&W format (2bit bitmap?).
What i need it to scan many small puzzle pieces;) and process them then so i need low-res B&W photos.

As I understand it, most USB cameras support video capture at a limited range of specific resolutions (see here for examples), which tend to be in standard aspect ratios (ratio of image width to height). I don’t think I’ve ever come across a camera that captures natively with the same width and height, as you described. I also don’t think I’ve ever used a USB camera that supported capturing at an arbitrary resolution. However, many cameras presumably come with software that supports image scaling and cropping after capture.

Anyway, let me suggest trying what I would use myself to do something like this: Capture the image at a higher resolution using RobotEyez or whatever you want and then use ImageMagick to scale and crop the image to the size and shape you want and to convert it to 1-bit black and white. ImageMagick is free software and it’s incredibly powerful and flexible. The only problem will be working out the exact command line to use with ImageMagick to convert your captured image.

For example, I tried the following ImageMagick command (the convert utility is one of the ImageMagick suite of tools):

As usual fantastic s/w. 🙂 Even I’d vote for the crop feature where perhaps we could pass the crop param line /cropW 100 /cropH 100 /CropX 250 /CropY 300 and it only saved the cropped part of the whole output for further processing.

I recommend taking a look at ImageMagick for doing the kind of post-capture processing you described. It’s a very mature free software project that will allow you to automate all kinds of image processing from a command line argument, as well as allowing conversion to different file formats. It’s free to download and install and there are lots of examples online showing how to apply different image processing operations. If you combine the RobotEyez command line and one or more ImageProcessing commands in a single batch file, you can automatically take a snapshot, crop it and convert it to whatever file format you prefer.

Ha ha, I thought of the same Ted. So I created 2 batch file, in 1 I had roboteyez and that calls the other batch having the Imagemagick command. For the benefit of someone looking to do it, here’s the code. hope it helps.

roboteyez was a great help for me! Thanks a lot…
I have now a problem by switching from windows7 to windows10 using Lifecam Studio camera and Lifecam HD3000 camera.
During the first call “c:\fotoprogramm\roboteyez.exe /width 1280 /height 720 /delay 3000 /bmp” the truecolor function of the camera (that adjusts color and brigthness) works.
Now the next pictures stay with these adjustments . eg I move the camera to the window, the picture is then nearly white (because it is too bright due to the sun).
If I unplug the camera and plug it in again, then again the first picture is adjusted….
Under Window7 the adjustment is done for every picture – now the adjustment is made only by the first usage.
The windows10 Camera application does always adjusts! But this does not influence roboteyez. So when I move the camera to the sun, then the Win10 camera application adjusts to the brightness. Afterwards when I call roboteyez again it uses the adjustment of the fist call!!
Do you have an idea, what I can do?? Thanks

Sorry, I have no idea why that’s happening. RobotEyez doesn’t really do much with the brightness settings, so if you’re having a problem with that I’d be inclined to try a different piece of software. Personally, I recommend trying ffmpeg. It’s free software, so you can either compile it from source by downloading it from here:

https://www.ffmpeg.org/download.html

…or else you can download a pre-built Windows executable from here:

http://ffmpeg.zeranoe.com/builds/

If you do a quick google, you’ll find examples of people using ffmpeg to do image capture from USB webcams that support DirectShow (windows video capture API). It’s an incredibly flexible and powerful piece of software and provides a ton of useful options that RobotEyez never will, so to be honest it’s probably a more future-proof solution.

I have one question though, Is it possible to control where the frame is saved?

In testing I have noticed that frames have been saved in my users home directory, the same directory as the script calling roboeyes, and system\sysWOW64! I think it is because the I am calling it from an elevated command prompt which I can’t change.

You should be able to set the location just by specifying the filename with a complete path. Alternatively, you could wrap roboteyez with a batchfile to save the snapshot to the current folder then transfer it to the desired location by moving the file.

CommandCam Copyright (C) 2012 Ted Burke
This program comes with ABSOLUTELY NO WARRANTY;
This is free software, and you are welcome to
redistribute it under certain conditions;
See the GNU General Public License v3,

Sorry, I haven’t tested RobotEyez on Windows 8 at all and I don’t have access to a Windows 8 machine to try it. In fact, I haven’t really looked at RobotEyez in quite a while because I’m working entirely on Linux now, so it’s awkward for me to compile Windows code. Best of luck finding a solution to your problem though!