#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <errno.h>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "fgrab_struct.h"
#include "fgrab_prototyp.h"
#include "fgrab_define.h"
#include "FastConfig.h"
Go to the source code of this file.
Classes | |
struct | tracking_window |
Keeps updated state information on the position of the ROI and the object being tracked. More... | |
struct | tracking_sequence |
A convenience structure containing the active ROIs and the order in which the ROIs are activated. More... | |
struct | frame_info |
timing information for a particular frame More... | |
struct | timing_info |
Global and local timing information. More... | |
Defines | |
#define | ONLINE 0 |
determines whether to use code meant for a live camera or images from a file | |
#define | MIN_SEQ_LEN 2 |
#define | ANIMATION_LENGTH 32 |
#define | ANIMATION_NAME "cross/Slide" |
#define | WHITE 255 |
#define | GRAY 128 |
#define | BLACK 0 |
#define | BACKGROUND BLACK |
#define | FOREGROUND WHITE |
#define | BORDER GRAY |
#define | OBJECT_FOUND 0 |
#define | TIMEOUT 5 |
#define | DO_INIT 1 |
#define | MAX_ROI 8 |
#define | PIXEL(win, i, j) ((win)->img[(j) + ((i) * (win)->roi_w)]) |
set or get the pixel at location [i , j ] in the tracking_window win pixel array. | |
Typedefs | |
typedef struct tracking_window | TrackingWindow |
the shorthand and actually used form of tracking_window | |
typedef struct tracking_sequence | TrackingSequence |
the shorthand and actually used form of tracking_sequence | |
typedef struct frame_info | FrameInfo |
typedef struct timing_info | TimingInfo |
Enumerations | |
enum | roi_index { ROI_0 = 0, ROI_1, ROI_2, ROI_3, ROI_4, ROI_5, ROI_6, ROI_7 } |
the eight indices enumerated as ROI_n More... | |
Functions | |
int | init_cam (Fg_Struct **grabber, int memsize, int buffers, int camlink) |
Initializes the framegrabber and camera. | |
int | acquire_imgs (Fg_Struct *fg, int *sequence, int seq_len) |
Transfers the initial region of interest (ROI) information to the frame grabber. | |
int | deinit_cam (Fg_Struct *fg) |
Stops grabbing images and frees resources associated with the frame grabber. | |
const unsigned long * | get_mem () |
Returns a pointer to buffer memory allocated by the frame buffer. | |
int | roi_sequence (Fg_Struct *fg, int *seq, int len) |
Writes the active ROI sequence to the frame grabber. | |
int | set_roi (int index, int width, int height, int exposure, int frame) |
int | roi_window (int index, int x, int width, int y, int height) |
Specifies the position in the image for index -th ROI. | |
int | roi_exposure (int index, double exp, double ft) |
Specifies the exposure and frame time of the image for index -th ROI. | |
int | roi_linlog (int index, int use_linglog, int ll1, int ll2, int comp) |
Specifies the linlog parameters of the image for index -th ROI. | |
int | write_roi (Fg_Struct *fg, int index, int imgNr, int doInit) |
Writes the ROI information of the index -th ROI to the frame grabber. | |
int | threshold (TrackingWindow *win, int t) |
binarizes an image | |
int | boundary (TrackingWindow *win) |
finds the boundary of an image | |
int | erode (TrackingWindow *win) |
a morphological operation that is useful for removing noisy FOREGROUND pixels. | |
int | time_run (TrackingSequence *tseq, int num_imgs, int t, double frame, double exposure) |
times different parts of the software | |
int | display_run (TrackingSequence *tseq, double frame, double exposure) |
shows the tracking software in action | |
void | set_roi_box (TrackingWindow *win, int x, int y) |
sets the ROI to be centered around point [x, y] in the image's coordinate system. | |
void | fix_blob_bounds (TrackingWindow *win) |
a helper function that converts the blob's initial position in the image coordinate system to the ROI coordinate system. | |
void | set_region (int e, int x, int y, int flags, void *param) |
an OpenCV mouse callback routine for the gui that sets the initial ROI locations and the initial blob bounding box. | |
int | position (TrackingWindow *cur) |
update the current TrackingWindow ROI for the next time it is active in the ROI sequence. | |
int | blob (TrackingWindow *win) |
produces a tight rectangular bounding box around the object | |
int | open_comm () |
int | write_comm (TrackingWindow *win, int box_x, int box_y) |
int | close_comm () |
int | StartGrabbing (Fg_Struct **fg, TrackingSequence *tseq, unsigned char **data) |
initialization routines for initializing and grabbing camera (or disk) images | |
void | CopyTrackingWindowToImage (TrackingWindow *win, IplImage *img) |
copies image data from the tracking window to an image | |
void | CopyImageToTrackingWindow (TrackingWindow *win, IplImage *img) |
copies image data from an image to the tracking window | |
void | PrintTimingData (Fg_Struct *fg, TimingInfo *timing_info) |
prints a summary of the timing tests performed on the vision system. | |
void | GetNextImage (IplImage **img, int nr, char *name, int seq_len, int show_name) |
Grabs the n-th image from file. | |
int | SetTrackCamParameters (TrackingWindow *win, double frame, double exposure) |
Combines routine startup code prior to writing the region of interest to the camera. |
#define ONLINE 0 |
determines whether to use code meant for a live camera or images from a file
ONLINE is a debugging switch for testing the system on images (ONLINE == 0) or is connected to the Photonfocus TrackCam camera (ONLINE != 0)
#define PIXEL | ( | win, | |||
i, | |||||
j | ) | ((win)->img[(j) + ((i) * (win)->roi_w)]) |
set or get the pixel at location [i
, j
] in the tracking_window win
pixel array.
i
, j
] is considered in the ROI reference frame.
typedef struct tracking_sequence TrackingSequence |
typedef struct tracking_window TrackingWindow |
enum roi_index |
the eight indices enumerated as ROI_n
roi_index is an simple way to refer to the 8 ROIs that the Silicon Software API allows.
int acquire_imgs | ( | Fg_Struct * | fg, | |
int * | seq, | |||
int | seq_len | |||
) |
Transfers the initial region of interest (ROI) information to the frame grabber.
acquire_imgs tells the frame grabber to start grabbing an infinite number of images. This function will also write the ROI parameters to the frame grabber. The active ROIs will become active on the camera in the order that seq
lists them. After cycling through the list, the sequence repeats itself from the beginning. A seq
cannot exceed 4,096 entires and seq_len
must equal the number of entries in seq
.
grabber | an initialized Fg_Struct object defined in the Silicon Software API | |
seq | the sequence specifying when a ROI is active | |
seq_len | the length of seq . |
int blob | ( | TrackingWindow * | win | ) |
produces a tight rectangular bounding box around the object
blob
finds an object in a given image as defined by the ROI and pixels in win->img
. This current implementation is a simple bounding box algorithm that assumes the image has been binarized before it attempts to find a blob.
win | the TrackingWindow to update the location of the object based on the image data and the ROI |
OBJECT_FOUND
, else !OBJECT_FOUND
int boundary | ( | TrackingWindow * | win | ) |
finds the boundary of an image
boundary
takes a TrackingWindow after the image data has been binarized and finds the boundary of the object
win | the TrackingWindow with the binarized image data |
void CopyImageToTrackingWindow | ( | TrackingWindow * | win, | |
IplImage * | img | |||
) |
copies image data from an image to the tracking window
CopyImageToTrackingWindow takes an image (typically from disk) and copies the image data to the tracking window. The data is expected to be an 8-bit gray scale image with at least enough pixels to fill up the tracking window's region of interest. In other words there must be roi_w x roi_h bytes in the image starting at location (roi_xoff, roi_yoff).
win | the destination TrackingWindow | |
img | the source image |
void CopyTrackingWindowToImage | ( | TrackingWindow * | win, | |
IplImage * | img | |||
) |
copies image data from the tracking window to an image
CopyTrackingWindowToImage takes the image data stored in the TrackingWindow and copies the image data to the image. The image buffer in img
must be able to hold an 8-bit gray scale image with roi_w x roi_h bytes starting at location (roi_xoff, roi_yoff) in the img
.
win | the source TrackingWindow | |
img | the destination image |
int deinit_cam | ( | Fg_Struct * | fg | ) |
Stops grabbing images and frees resources associated with the frame grabber.
deinit_cam stops the frame grabber from acquiring images and frees the resources used by the frame grabber.
grabber | an initialized Fg_Struct object defined in the Silicon Software API |
int display_run | ( | TrackingSequence * | tseq, | |
double | frame, | |||
double | exposure | |||
) |
shows the tracking software in action
display_run
shows a GUI with a live video feed from a camera or a collection of files from disk with the tracking algorithm running in the background. The GUI displays a gray rectangle representing a ROI and a smaller gray rectange inside the ROI representing the blob's bounding box. The user can set the desired threshold value and reposition the ROI at any time. The GUI reacts to the following commands when a keyboard button is pressed:
Notation: let 'x' represent the corresponding character on the keyboard let '0-9' represent either the 0, 1, 2, 3,..., 9 buttons on the keyboard let 'RMB' mean pressing the right mouse button let 'HLMB' mean hold the left mouse button down
To relocate the i-th ROI, press 'i': to enter relocate mode for the ROI '0-7': to select a particular ROI 'RMB': to finally reposition the ROI
To set the object's bounding box, press: 'HLMB': drag the mouse inside the ROI to draw the object's bounding box after drawing the desired box release the 'HLMB'
To threshold the image bounded by a ROI, press 't': to enter threshold mode (make sure to set the object bounding box first!!!) adjust the slider to the desired value located at the top of the GUI
To track an object, press 'p': to start the tracking (make sure to position the ROI and object bounding box)
To step through the images in the GUI frame by frame, press: 's': to enter step mode press any key, but 's' to advance to the next frame
To get help, press: 'h': to print a help message
To quite the GUI, press: 'q': to quit
tseq | the TrackingSequence specifying the active ROIs and their initial positions in the image prior to tracking an object | |
frame | the frame time (e.g. length of time between images) in microseconds | |
exposure | the exposure time (e.g. length of time the shutter is kept open) in microseconds |
int erode | ( | TrackingWindow * | win | ) |
a morphological operation that is useful for removing noisy FOREGROUND
pixels.
erode
takes a TrackingWindow after the image data has been binarized and removes stray FOREGROUND
pixels that appear to be noise.
win | the TrackingWindow with the binarized image data |
void fix_blob_bounds | ( | TrackingWindow * | win | ) |
a helper function that converts the blob's initial position in the image coordinate system to the ROI coordinate system.
win | the TrackingWindow's ROI to fix. |
fix_blob_bounds
maps the blob's initial position to the ROI reference frame and it also fixes the bounds if the resulting points are outside the ROI window.
void GetNextImage | ( | IplImage ** | img, | |
int | nr, | |||
char * | name, | |||
int | seq_len, | |||
int | show_name | |||
) |
Grabs the n-th image from file.
GrabNextImage is meant to be an alternative to Fg_getLastPicNumberBlocking (see Silicon Software SDK doc). The behavior is similar to Fg_getLastPicNumberBlocking. The only difference is that the images are loaded from disk as oppose to being grabbed from the camera.
There are a few particular things to keep in mind about this function call. First, similarly to Fg_getLastPicNumberBlocking, the desired image number (nr
) can be any non-negative value. If nr
is greater than the number of frames on disk, then the nr
% seq_len
is returned.
The name of the image format must be name
x.jpg, where name
is the base file name of a jpeg image file and x is the x-th image in the sequence. The first image must have x = 0 and the last image must have x = seq_len
- 1. Also, x must contain all integer values between 0 and seq_len
- 1.
Images are loaded by counting up from 0 to seq_len
- 1 and then counting back down to 0. This process is repeated indefinitely. If a different base name is used GrabNextImage will not reset itself and automatically count up. Instead, it will continue counting in the same direction as its previous call. To change directions set nr
= 0.
Finally, img
does not have to be uninitialized. If img
already points to a preexiting image, then the image will be released prior to loading the next image in the sequence.
img | the destination where the image will be loaded into | |
nr | the desired image to load | |
name | the base name of the jpeg file | |
seq_len | the length of the sequence on disk | |
show_name | if true, displays the name of the loaded jpeg file |
int init_cam | ( | Fg_Struct ** | grabber, | |
int | memsize, | |||
int | buffers, | |||
int | camlink | |||
) |
Initializes the framegrabber and camera.
init_cam performs the necessary initialization routines prior to acquiring images. memsize
should equal the image width x image height x buffers
. Although this is not enforced, undesired behavior may result.
grabber | an uninitialized Fg_Struct object defined in the Silicon Software API | |
memsize | the image buffer memory size in bytes | |
buffers | the number of buffer to divide the memsize bytes into | |
camlink | the camera link type as defined in the Silicon Software API |
FG_CL_DUALTAP_8_BIT
in order to maximize the number of pixel information that can be sent over the cable (physically) connecting the framegrabber and camera. int position | ( | TrackingWindow * | cur | ) |
update the current TrackingWindow ROI for the next time it is active in the ROI sequence.
position
searches for the blob in an image and updates the TrackingWindow with the new blob and ROI positions for the next time the TrackingWindow is active.
cur | the current TrackingWindow to update with new position information |
OBJECT_FOUND
, else !OBJECT_FOUND
blob
to find the object and then calls set_roi_box
to center the ROI around the center of the blob's bounding box. Careful modification of these two functions may improve the tracking capabilities of the vision system with more complex algorithms that still meet the desired timing constraints. void PrintTimingData | ( | Fg_Struct * | fg, | |
TimingInfo * | timer | |||
) |
prints a summary of the timing tests performed on the vision system.
PrintTimingData is meant to be used in conjunction with the TimingInfo structure. It will print out a summary of the parameters used in the vision system and a table of timing data for different aspects of it. If images were not grabbed from the TrackCam camera set fg = NULL.
fg | the frame grabber structure (see Silicon Software SDK doc), which can be NULL | |
timer | the data structure containing all of the relevant timing information |
TimingInfo
int roi_exposure | ( | int | index, | |
double | exp, | |||
double | ft | |||
) |
Specifies the exposure and frame time of the image for index
-th ROI.
This function specifies the exposure (length of time the camera's shutter is open) and the frame time (length of time until the next image is taken, e.g. the inverse of the frame rate), both in microseconds, that the camera will snap a picture.
Because the frame grabber only supports 8 ROIs, index
must lie between 0 and 7 (e.g. ROI_0 <= index
<= ROI_7). Finally, the ROI specified by index
is NEVER written to the camera. You must call write_roi
after calling this function for changes to take effect.
index | the ROI where the parameters are saved | |
exp | the exposure time in microseconds | |
ft | the frame time in microseconds |
int roi_linlog | ( | int | index, | |
int | use_linlog, | |||
int | ll1, | |||
int | ll2, | |||
int | comp | |||
) |
Specifies the linlog parameters of the image for index
-th ROI.
This function specifies the linlog parameters (camera-specific technology that can be found in the Photonfocus TrackCam documentation).
Because the frame grabber only supports 8 ROIs, index
must lie between 0 and 7 (e.g. ROI_0 <= index
<= ROI_7). Finally, the ROI specified by index
is NEVER written to the camera. You must call write_roi
after calling this function for changes to take effect.
index | the ROI where the parameters are saved | |
use_linlog | a boolean value (0 = FALSE) | |
ll1 | linlog parameter 1 (see Photonfocus doc for description) | |
ll2 | linlog parameter 2 (see Photonfocus doc for description) | |
comp | compensation parameter (see Photonfocus doc for description) |
int roi_sequence | ( | Fg_Struct * | fg, | |
int * | seq, | |||
int | len | |||
) |
Writes the active ROI sequence to the frame grabber.
This function writes the ROI parameters to the frame grabber. The active ROIs will become active on the camera in the order that seq
lists them. After cycling through the list, the sequence repeats itself from the beginning. A seq
cannot exceed 4,096 entires and seq_len
must equal the number of entries in seq
.
grabber | an initialized Fg_Struct object defined in the Silicon Software API | |
seq | the sequence specifying when a ROI is active | |
len | the length of seq . |
int roi_window | ( | int | index, | |
int | x, | |||
int | width, | |||
int | y, | |||
int | height | |||
) |
Specifies the position in the image for index
-th ROI.
This function specifies what portion of the pixel array on the camera will be transferred up to the application. The window is defined relative to the pixel coordinate system with [0,0] located in the top-most left corner of an image. The window will be placed starting at the the top-most [x,y] pixel coordinate with width
and height
.
Because the frame grabber only supports 8 ROIs, index
must lie between 0 and 7 (e.g. ROI_0 <= index
<= ROI_7). Finally, the ROI specified by index
is NEVER written to the camera. You must call write_roi
after calling this function for changes to take effect.
index | the ROI where the parameters are saved | |
x | the topmost x (or column) position in pixels | |
y | the topmost y (or row) position in pixels | |
width | the width of the window | |
height | the height of the window |
void set_region | ( | int | e, | |
int | x, | |||
int | y, | |||
int | flags, | |||
void * | param | |||
) |
an OpenCV mouse callback routine for the gui that sets the initial ROI locations and the initial blob bounding box.
set_region
is used in the initialization of the system. The blob is in an unknown location and with the assistance of this function, the GUI shown (like in display_run.cpp) assists the user in setting the initial position of the object. Currently, dragging the left mouse button set the blob's parameters and pressing the right mouse button causes the ROI to be centered around that click. The function's prototype is specified in the OpenCV documentation. Go there for more details about callbacks in OpenCV
e | the mouse event | |
x | the x coordinate of the click in the GUI reference frame (e.g. the image reference frame). | |
y | the y coordinate of the click | |
flags | special keyboard modifier keys | |
param | an optional parameter to pass into the routine. It is used to pass the current TrackingWindow. |
void set_roi_box | ( | TrackingWindow * | win, | |
int | x, | |||
int | y | |||
) |
sets the ROI to be centered around point [x, y] in the image's coordinate system.
set_roi_box
centers a TrackingWindow
ROI around [x, y] and updates the ROI in the system. It is still required to call write_roi
in order for the frame grabber to receive the updated values.
win | the TrackingWindow containing the ROI to update | |
x | the x value to center the ROI around (0 <= x <= win->img_w) | |
y | the y value to center the ROI around (0 <= y <= win->img_h) |
set_roi_box
will center around [x, y] such that the roi_x and roi_w are multiples of 4 and roi_w is greater than 8. The former is a documented limitation in the Silicon Software API and the latter has been determined through observation. If win->roi_w
<= 8, then the camera hangs and does not send back any more images. It has not been tested to see if this bug is only isolated to the one desktop this code was developed on.
it is important to reiterate that the updated ROI returned by this functions is NOT written to the frame grabber. A call to write_roi
is still required.
int SetTrackCamParameters | ( | TrackingWindow * | win, | |
double | frame, | |||
double | exposure | |||
) |
Combines routine startup code prior to writing the region of interest to the camera.
SetTrackCamParameters will copy the desired position, window size, frame, and exposure time into the internal cam.cpp ROI structure. It will also set the rarely used linlog parameters (see Silicon Software doc) to USELINLOG, LINLOG1, LINLOG2, COMP
.
win | the tracking window with win->roi, win->roi_xoff, win->roi_w, win->roi_yoff, win->roi_h set to reasonable values (see note below) | |
frame | the frame time in microseconds (i.e. length of time between images) | |
exposure | the exposure time in microseconds (i.e. length of time camera shutter is open) |
int StartGrabbing | ( | Fg_Struct ** | fg, | |
TrackingSequence * | tseq, | |||
unsigned char ** | data | |||
) |
initialization routines for initializing and grabbing camera (or disk) images
StartGrabbing is a wrapper routine for typical startup code when grabbing from a camera or disk. If ONLINE
is true then fg
must not be NULL, otherwise if ONLINE
is false, then data
must not be NULL.
fg | a pointer to the Silicon Software frame grabber structure (see Silicon Software SDK doc) [if ONLINE = 1] | |
tseq | the sequence in which the ROI are active (if ONLINE = 1) | |
data | the buffer that will eventually hold the image data (if ONLINE = 0) |
int threshold | ( | TrackingWindow * | win, | |
int | t | |||
) |
binarizes an image
threshold
takes a TrackingWindow and binarizes the data based on the threshold level, t
. All values less than t
are colored as BACKGROUND
pixels, otherwise the pixel is a FOREGROUND
pixel.
win | the TrackingWindow to threshold | |
t | the threshold value |
int time_run | ( | TrackingSequence * | tseq, | |
int | num_imgs, | |||
int | t, | |||
double | frame, | |||
double | exposure | |||
) |
times different parts of the software
time_run
acquires num_imgs
and times several functions in a tight loop. At the end of each run the results are printed to stdout, which can then be piped to a file or another program for further processing.
tseq | the TrackingSequence specifying the active ROIs and their initial positions in the image prior to tracking an object | |
t | the threshold value to be used with threshold | |
frame | the frame time (e.g. length of time between images) in microseconds | |
exposure | the exposure time (e.g. length of time the shutter is kept open) in microseconds |
int write_roi | ( | Fg_Struct * | fg, | |
int | index, | |||
int | imgNr, | |||
int | doInit | |||
) |
Writes the ROI information of the index
-th ROI to the frame grabber.
write_roi writes any changes made to the index
-th ROI. The camera is programmed with the updated changes no sooner than the imgNr
image has been taken by the camera. If the camera is triggered via external hardware, camera self-trigger (a.k.a free running), or frame grabber then doInit
is FALSE, otherwise the camera is software triggered and it must be TRUE for changes to take place. For more information about the triggering modes consult the Silicon software API.
grabber | an initialized Fg_Struct object defined in the Silicon Software API | |
index | the ROI where the parameters are saved | |
imgNr | the (minimum) image that the ROI will be active for | |
doInit | perform a reinitialization of the camera ROI (see Silicon Software API) |