
Recently, I needed to receive data from a webcam for automatic processing. After going through several programs, I found that none of them allows the camera to steer the program programmatically - only forms and buttons, at best there is a recording scheduler, but for this you have to keep the program running all the time. Plus is not cross-platform, binding to specific software in the project. The solution is to use your favorite programming language.
So, we have a webcam and a python. First of all, one cannot fail to praise the camera that I purchased at
dealextreme : a baby about half the size of a matchbox, works in Windows and Linux without installing third-party software (checked in Win 7 and Mint 13, turned on - and went), acceptable quality and price. When working, the camera does not present itself as burning indicators or other effects. Small sizes contribute to its inconspicuous installation.

Since I work in both Windows and Linux, the solution should satisfy both OSs. The library of computer vision OpenCV and its binding for Python will help. An alternative solution could be
video4linux . But, firstly, it was interesting for me to learn OpenCV, and secondly, about using v4l was already a
great habstatia .
')
Install the numpy and opencv libraries. Linux users open a terminal and write:
sudo apt-get install python-numpy sudo apt-get install python-opencv
Those who are under Windows
go here and extort the
numpy and
opencv distributions under the desired version of Python.
For Windows there is an alternative method of installation. Enough to download the
official distribution of the library. In the archive we find /build/python/2.x/cv2.pyd. We throw it in site-packages. In the same place we create a file cv.py with the contents:
from cv2.cv import *
All is ready. Test import:
import cv
We will use part of the library called
higui . We start the experiments. Trial ball - getting the frame and writing it to the file:
import cv capture = cv.CaptureFromCAM(0) frame = cv.QueryFrame(capture) cv.SaveImage("capture.jpg", frame)
The
CaptureFromCAM function creates an object from which the capture will occur. 0 is the device index, it can be greater than zero if there are several cameras. A value of -1 carries the meaning of “any available camera.”
Now you can start frame collection in a loop. It would be great if the frames will be displayed along the way in a separate window:
import cv capture = cv.CaptureFromCAM(-1) cv.NamedWindow("capture", cv.CV_WINDOW_AUTOSIZE) i = 0 while True: frame = cv.QueryFrame(capture) cv.ShowImage("capture", frame) cv.WaitKey(10) path = "capture%.4d.jpg" % i # cv.SaveImage(path, frame) i += 1
The
NamedWindow function creates and displays a window in which it is output in a loop each frame. The
WaitKey handler sets the delay in milliseconds for handling window events, such as pressing a key or displaying an image. If you omit it, the window will not display frames (and, possibly, will not appear at all).
Capture frames in action. The camera looks at the monitor, so a recursion occurs - a deckstop, inside of which is a desktop, inside of which ...Collecting multiple frames is useful when you need to insert a time pause between snapshots, for example, 1 frame every minute. It is enough to substitute time.sleep (60) into the loop.
If continuous shooting is required, you need to record frames in a video stream.
import cv capture = cv.CaptureFromCAM(-1) fourcc = cv.CV_FOURCC('M','J','P','G') fps = 16 w, h = 640, 480 stream = cv.CreateVideoWriter("test.avi", fourcc, fps, (w, h)) while True: frame = cv.QueryFrame(capture) cv.WriteFrame(stream, frame)
At first glance, everything is also obvious here: the
CreateVideoWriter function creates a stream to which frames are written. It is enough to interrupt the cycle to get the finished video file. However, you should understand the input parameters.
fourcc is a codec, an integer, the result of mapping a four-
character codec name to a numeric index. For example, CV_FOURCC ('P', 'I', 'M,' 1 ') is MPEG-1 compression. In Windows, you can pass -1 for selecting the codec interactively in the dialog box or 0 for recording without compression (the file size will turn out th!). Habrawar
Elsedar tells you where to see the full list of codecs:
www.fourcc.org/codecs.phpfps is the frame rate per second. The parameter directly depends on the model of your camera. At this point, the real state of affairs went against the documentation. It is believed that the recording parameters should not be set by eye, but in an exact way, for which the
GetCaptureProperty function
serves . It can get device parameters for correct initialization of capture. But if the height and width of the frame are retrieved without problems, then getting fps:
fps = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FPS)
returns -1, which will not satisfy the CreateVideoWriter function, so the frequency is chosen empirically. As a rule, for most cameras it ranges from 14 to 16 frames per second. If you set 25, the resulting file will resemble a silent movie of the 20s.
The last parameter of
frame_size is a pair of integer numbers of the height and width of the frame. To use the camera settings, initialize them as follows:
w = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH) h = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT) w, h = int(w), int(h) # float
Now you can touch on the theme of color correction. If the output frames do not suit you, it is quite reasonable to correct the capture parameters, rather than batching overtaking the mountains of dzhipegov or hours of video. To set the parameters there is a function
SetCaptureProperty . It is convenient to fill in several properties by searching the dictionary:
config = { cv.CV_CAP_PROP_BRIGHTNESS: 50, cv.CV_CAP_PROP_CONTRAST: 50, cv.CV_CAP_PROP_SATURATION: 50, } for param, value in config.iteritems(): cv.SetCaptureProperty(capture, param, value)
The parameters of brightness, contrast and saturation are set in the range from 1 to 100. Their combination can significantly improve the quality of shooting in darkened rooms.
A few examples:
Frame with default parameters
Brightness, contrast and saturation equal to 50 points.
Brightness 50, contrast 70, saturation 0It so happens that the frames from the camera need to be processed by the library PIL. To convert them from cv format to PIL, it is not necessary to save them to disk, just run the code:
pil_img = Image.fromstring("L", cv.GetSize(frame), frame.tostring())
And in the opposite direction:
cv_img = cv.CreateImageHeader(pil_img.size, cv.IPL_DEPTH_8U, 3) cv.SetData(cv_img, pil_img.tostring())
As a result, we have programmatic access to the camera, we can take shots and send them by mail, do some kind of analysis, write video. Cross platform solution. I think it is easy to stream. Here, by the way, the program with the GUI interface on wx by itself, for example, suggests.
References:
1) OpenCV library
2) Binding documentation for Python
3) Section "highgui"