// VideoTool.cpp : Defines the entry point for the console application.
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <tchar.h>
#include <math.h>
// TODO: reference additional headers your program requires here
#include "cv.h"
#include "highgui.h"
// ARGH! why is this necessary ??
#define _NO_HMC_WINSOCK_
#include "SmallSocket.h"
#undef _NO_HMC_WINSOCK_
using namespace std;
// these are the two functions you'll need to write
void RGBtoHSV( double r, double g, double b, double *h, double *s, double *v );
void processRed( IplImage* frame, IplImage* f_p );
void setGlobals(); // the code appears at the very bottom of this file
char wndname[] = "VideoTool";
char wndname2[] = "Undistorted image";
char wndname3[] = "Painted image";
// here, static refers to the fact that these variables
// are local to this file (they're not available in other files,
// which is safer because it allows reuse of their names)
static CvSize imageSize;
static CvPoint old_click_pt;
static CvPoint new_click_pt;
static double framenum;
// global points for drawing boxes, defining loops, etc.
static CvPoint pt1;
static CvPoint pt2;
static CvPoint pt3;
static CvPoint pt4;
static CvPoint pt5;
static CvPoint pt6;
static CvPoint pt7;
// global calibration data
static float* M;
static float* D;
// more global variables
// these are simply recording all the different states you
// can put the program in via the keyboard
static bool bmpRecording = false;
static bool capturing = true;
static bool getImageFromFile = false;
static bool getImageAgainFromFile = false;
static bool getImage0FromVideoBMPs = false;
static bool saveNextImage = false;
static bool quittingTime = false;
static bool detectRed = false;
static bool showing_savedImage = false;
static char* filename = new char[150];
static char* filename2 = new char[150];
static int frameNumber = 0;
static int keyCode = -1;
// pointers to images in memory
static IplImage *frame;
static IplImage* undis_frame;
static IplImage* undis_frame_painted;
static CvArr* undisMap;
// globals for tuning parameters by keyboard...
static int blueValue = 255;
/*
static int redHueHighSatLowerBound = 320;
static int redHueHighSatUpperBound = 25;
static int redHueLowSatLowerBound = 320;
static int redHueLowSatUpperBound = 25;
*/
static int redHueLowerBound = 320;
static int redHueUpperBound = 25;
static int numInCenter = 7;
bool isRed(double h, double s, double v)
{
//double lowerbound = (redHueHighSatLowerBound - redHueLowSatLowerBound) * val + redHueLowSatLowerBound;
//double upperbound = (redHueHighSatUpperBound - redHueLowSatUpperBound) * val + redHueLowSatUpperBound;
if ((h > redHueLowerBound || h < redHueUpperBound) && s > 0.15)
return true;
return false;
}
// handle mouse clicks here
void mouse_callback(int event, int x, int y, int flags)
{
if (event == CV_EVENT_LBUTTONDOWN)
{
// cout << "(x,y) = (" << x << "," << y << ")" << endl;
// reset old_click_pt
old_click_pt.x = new_click_pt.x;
old_click_pt.y = new_click_pt.y;
// get new click point -- note the coordinate change in y
new_click_pt.x = x; // coming in from the window system
new_click_pt.y = imageSize.height-y; // window system and images have different y axes
}
}
// print pixel information
void pixelInformation(IplImage* f)
{
if (f == NULL) return;
// see if things have changed...
if (new_click_pt.x != old_click_pt.x || new_click_pt.y != old_click_pt.y) // has it changed?
{
// draw a line from old to new
// cvLine(frame,old_click_pt,new_click_pt,CV_RGB(255,0,0),/*thickness*/1,/*connectivity*/8);
// set the old = the new
old_click_pt.x = new_click_pt.x;
old_click_pt.y = new_click_pt.y;
// print the RGB values and coordinates of the newly clicked point:
// note that blue is #0, green is #1, and red is #2 !!
/* note that this uses the undistorted frame right here... */
// this is insane!!!
// see the processRed function for an explanation
// of why we need "realy"
int realy = new_click_pt.y;
if (getImageAgainFromFile || getImageFromFile)
{
realy = imageSize.height - realy;
}
uchar* pixel = cvPtr2D(f,realy,new_click_pt.x);
cout << "(x,y) = (" << new_click_pt.x << "," << new_click_pt.y << ") with (r,g,b) = ("
<< (int)(pixel[2]) << "," << (int)(pixel[1]) << "," << (int)(pixel[0]) << ")";
double hue,sat,val;
RGBtoHSV((double)pixel[2],(double)pixel[1],(double)pixel[0],&hue,&sat,&val);
cout << " and (h,s,v) = (" << hue << "," << sat << "," << val << ")" << endl;
}
}
// the thread for the server
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
char recvbuf[80];
char sendbuf[80];
string t("HI");
SmallSocket SS(SmallSocket::SERVER);
sprintf( recvbuf, "Server Started", *(DWORD*)lpParam );
//MessageBox( NULL, szMsg, "ThreadFunc", MB_OK );
while (true)
{
SS.receive(recvbuf,80);
cout << "Received: " << recvbuf << endl;
if (recvbuf[0] == 'q') {
SS.sendout("q",2);
// set a variable that tells it to quit...
quittingTime = true;
// cvReleaseCapture( &capture );
// cvDestroyWindow("result");
break;
}
if (recvbuf[0] == 'e') {
// just an example of passing in more information
// and using sscanf to extract it
// sscanf(recvbuf,"q %lf %lf %lf ",&savedXforLog,&savedYforLog,&savedTforLog);
//
//the connection requires that something come back...
// note that we're sending two zeros every time here...
sprintf(sendbuf, "%d %d", 0, 0);
SS.sendout(sendbuf,80);
}
// pause for a bit...
Sleep(10);
}
return 0;
}
int main( int argc, char** argv )
{
// in case you want to log things...
//ofstream logfile("logfile_out.txt");
//ifstream loginfile("logfile_in.txt");
// set up the globals...
setGlobals();
// start the server's thread
// make sure that all imageprocessing is in main's thread
DWORD dwThreadId, dwThrdParam = 1;
HANDLE hThread;
char szMsg[80];
hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunc, // thread function
&dwThrdParam, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
// Check the return value for success.
if (hThread == NULL)
{
sprintf( szMsg, "CreateThread failed." );
MessageBox( NULL, szMsg, "main", MB_OK );
}
/*
* set up the video windows
*/
cvNamedWindow( wndname, CV_WINDOW_AUTOSIZE );
cvNamedWindow( wndname2, CV_WINDOW_AUTOSIZE );
cvNamedWindow( wndname3, CV_WINDOW_AUTOSIZE );
/*
* set up the mouse input
*/
//cvSetMouseCallback( wndname, mouse_callback );
cvSetMouseCallback( wndname2, mouse_callback );
/*
* more camera-specific stuff
*/
CvCapture* capture = 0;
capture = cvCaptureFromCAM(0);
// this is allocating the undis_frame once (it will get written each time)
// get one frame and then copy it...
if (cvGrabFrame(capture))
{
frame = cvRetrieveFrame( capture );
undis_frame = cvCloneImage(frame);
undis_frame_painted = cvCloneImage(frame);
// now let's set up the undistortion parameters
// note that the docs say 3*wider, but that did not work
// 3*wider _and_ 3*higher worked...
undisMap = cvCreateMat( imageSize.width*3, imageSize.height*3, CV_32SC3 );
// need to release this at the end of the program...
cvUnDistortInit( frame, undisMap, M, D, 1 );
}
else
{
cout << "No camera??" << endl;
capturing = false;
}
// main loop
while (!quittingTime)
{
if (capturing)
{
if( !cvGrabFrame( capture )) break;
frame = cvRetrieveFrame( capture );
if( !frame ) break;
// cvUnDistortOnce( frame, undis_frame, M, D, 1 ); // might take some extra time...
cvUnDistort( frame, undis_frame, undisMap, 1 );
cvReleaseImage(&undis_frame_painted);
undis_frame_painted = cvCloneImage(undis_frame);
}
else if (getImageFromFile || getImageAgainFromFile)
{
if (getImageFromFile) {
// ask for a frame filename
int i;
// should factor this path out!!
if (getImage0FromVideoBMPs) {
i = 0;
getImage0FromVideoBMPs = false;
}
else {
cout << "What image number (in C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\VideoBMPs): ";
cin >> i;
}
sprintf(filename2,"C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\VideoBMPs\\image%05d.bmp",i);
// we probably need to release the images returned by cvLoadImage somewhere...
//frame = cvLoadImage(filename2);
//undis_frame = cvCloneImage(frame);
cvReleaseImage(&undis_frame);
undis_frame = cvLoadImage(filename2);
cvReleaseImage(&undis_frame_painted);
undis_frame_painted = cvLoadImage(filename2);
if (undis_frame == NULL) {
cout << "Could not find that image.\n";
continue;
}
getImageFromFile = false;
getImageAgainFromFile = true;
}
else if (getImageAgainFromFile) {
cvReleaseImage(&undis_frame_painted);
undis_frame_painted = cvCloneImage(undis_frame);
}
}
else
{
;
}
// click only on undis_image
pixelInformation(undis_frame_painted);
// save the images to a file, if desired
if (bmpRecording == true && capturing == true)
{
sprintf(filename,"C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\BMPs\\image%05d.bmp",frameNumber);
cout << "Captured single image (dist): " << filename << endl;
cvSaveImage(filename,frame);
sprintf(filename2,"C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\BMPsUnd\\image%05d.bmp",frameNumber);
cout << "Captured single image (undist): " << filename2 << endl;
cvSaveImage(filename2,undis_frame);
++frameNumber;
//saveNextImage = false;
//if (getImageFromFile) {
// bmpRecording = false;
//}
}
// here we can add graphics to each frame
// in order that they show up on the screen
// we also decide what to display in this routine
if (detectRed == true)
{
processRed(undis_frame,undis_frame_painted);
}
/*
* display everything in the windows
*/
cvShowImage(wndname, frame);
cvShowImage(wndname2, undis_frame);
cvShowImage(wndname3, undis_frame_painted);
//handle key presses
/*
* quits
*/
if( (keyCode = cvWaitKey( 10 )) == ((int)'q') ) {
break; // quit everything
}
/*
* we use = and - to increase and decrease blueValue
*/
else if (keyCode == (int)'=') {
if (blueValue < 251) blueValue += 5;
}
else if (keyCode == (int)'-') {
if (blueValue > 4) blueValue -= 5;
}
/*
* we use n and m to increase and decrease redLowerBound,
* and , and . to increase and decrease redUpperBound.
*
else if (keyCode == (int)'n') {
if (redHueLowSatLowerBound - 1 > redHueLowSatUpperBound) --redHueLowSatLowerBound;
cout << "Low Saturation Red is [" << redHueLowSatLowerBound << "..." << redHueLowSatUpperBound << "]" << endl;
}
else if (keyCode == (int)'m') {
if (redHueLowSatLowerBound + 1 <= 360) ++redHueLowSatLowerBound;
cout << "Low Saturation [" << redHueLowSatLowerBound << "..." << redHueLowSatUpperBound << "]" << endl;
}
else if (keyCode == (int)',') {
if (redHueLowSatUpperBound - 1 >= 0) --redHueLowSatUpperBound;
cout << "Low Saturation [" << redHueLowSatLowerBound << "..." << redHueLowSatUpperBound << "]" << endl;
}
else if (keyCode == (int)'.') {
if (redHueLowSatUpperBound + 1 < redHueLowSatLowerBound) ++redHueLowSatUpperBound;
cout << "Low Saturation [" << redHueLowSatLowerBound << "..." << redHueLowSatUpperBound << "]" << endl;
}
else if (keyCode == (int)'j') {
if (redHueHighSatLowerBound - 1 > redHueHighSatUpperBound) --redHueHighSatLowerBound;
cout << "High Saturation [" << redHueHighSatLowerBound << "..." << redHueHighSatUpperBound << "]" << endl;
}
else if (keyCode == (int)'k') {
if (redHueHighSatLowerBound + 1 <= 360) ++redHueHighSatLowerBound;
cout << "High Saturation [" << redHueHighSatLowerBound << "..." << redHueHighSatUpperBound << "]" << endl;
}
else if (keyCode == (int)'l') {
if (redHueHighSatUpperBound - 1 >= 0) --redHueHighSatUpperBound;
cout << "High Saturation [" << redHueHighSatLowerBound << "..." << redHueHighSatUpperBound << "]" << endl;
}
else if (keyCode == (int)';') {
if (redHueHighSatUpperBound + 1 < redHueHighSatLowerBound) ++redHueHighSatUpperBound;
cout << "High Saturation [" << redHueHighSatLowerBound << "..." << redHueHighSatUpperBound << "]" << endl;
}
*/
/*
* records video to bitmaps (files)
*/
else if (keyCode == (int)'f') {
if (bmpRecording) {
cout << "Stopping the writing to bitmaps\n";
bmpRecording = false;
} else {
cout << "Starting to write to bitmaps\n";
bmpRecording = true;
}
showing_savedImage = false;
}
/*
* gets image from a file # in ./VideoBMPs
*/
else if (keyCode == (int)'g') {
cout << "Getting image from file.\n";
capturing = false;
getImageFromFile = true;
getImageAgainFromFile = false;
bmpRecording = false;
saveNextImage = false;
showing_savedImage = true;
}
/*
* toggle continuous video
*/
else if (keyCode == (int)'s') {
if (capturing) {
cout << "Stopping continuous capturing.\n";
capturing = false;
getImageFromFile = false;
}
else {
cout << "Starting continuous capturing.\n";
capturing = true;
getImageFromFile = false;
getImageAgainFromFile = false;
/* reset undis_image */
// note this assumes that everything went well
// initially with the first captured frame... !!
cvReleaseImage(&undis_frame);
undis_frame = cvCloneImage(frame);
cvReleaseImage(&undis_frame_painted);
undis_frame_painted = cvCloneImage(frame);
// not to mention that these transition images have to be released!
}
showing_savedImage = false;
}
else if (keyCode == (int)'e') {
// emulate server behavior
saveNextImage = true;
showing_savedImage = false;
}
/*
* toggle finding red (and displaying)
*/
else if (keyCode == (int)'r') {
detectRed = !detectRed;
cout << "Toggled red detection. Red detection is ";
cout << (detectRed ? "active." : "inactive") << endl;
}
/*
* the spacebar advances the image in the VideoBMPs directory
*/
else if (keyCode == (int)' ') {
if (showing_savedImage == true)
{
int i;
sscanf(filename2,"C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\VideoBMPs\\image%05d.bmp",&i);
sprintf(filename2,"C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\VideoBMPs\\image%05d.bmp",++i);
cvReleaseImage(&undis_frame);
undis_frame = cvLoadImage(filename2);
cvReleaseImage(&undis_frame_painted);
undis_frame_painted = cvLoadImage(filename2);
// wrap around!
if (undis_frame == NULL)
{
i = 0;
sprintf(filename2,"C:\\Program Files\\ERSP\\sample_code\\driver\\VideoTool\\VideoBMPs\\image%05d.bmp",i);
cvReleaseImage(&undis_frame);
undis_frame = cvLoadImage(filename2);
cvReleaseImage(&undis_frame_painted);
undis_frame_painted = cvLoadImage(filename2);
continue;
}
getImageAgainFromFile = true;
getImageFromFile = false;
}
/*
* initial hit of the space bar...
*/
else {
cout << "No image from file is currently showing..." << endl;
cout << "Getting image 0 from VideoBMPs.\n";
capturing = false;
getImageFromFile = true;
getImageAgainFromFile = false;
getImage0FromVideoBMPs = true;
bmpRecording = false;
saveNextImage = false;
showing_savedImage = true;
}
}
}
// release things before quitting
cvReleaseCapture( &capture );
cvDestroyWindow("result");
} // end of main
// just in case you'd like to use these...
inline double mymin(double a, double b) { return a<b?a:b; }
inline double mymax(double a, double b) { return a>b?a:b; }
// read about HSV at http://en.wikipedia.org/wiki/HSV_color_space
// and http://www.cs.rit.edu/~ncs/color/t_convert.html#RGB%20to%20HSV%20&%20HSV%20to%20RGB
//
// The function below was copied directly from the second webpage cited above and tweaked only slightly.
//
void RGBtoHSV( double r, double g, double b, double *h, double *s, double *v )
{
r = r/255;
g = g/255;
b = b/255;
double min, max, delta;
min = mymin(mymin( r, g), b );
max = mymax(mymax( r, g), b );
*v = max; // v
delta = max - min;
if( max != 0 )
*s = delta / max; // s
else {
// r = g = b = 0 // s = 0, v is undefined
*s = 0;
*h = -1;
return;
}
if( r == max )
*h = ( g - b ) / delta; // between yellow & magenta
else if( g == max )
*h = 2 + ( b - r ) / delta; // between cyan & yellow
else
*h = 4 + ( r - g ) / delta; // between magenta & cyan
*h *= 60; // degrees
if( *h < 0 )
*h += 360;
}
// here is where we seek out the red molding and indicate what we've found
// the input named "frame" is the source location of our pixels
// the "output" named f_p is the destination for drawing
void processRed(IplImage* frame, IplImage* f_p)
{
// some useful local variables...
int r,g,b;
double hue,sat,val;
// pixels are handled as uchar*'s
uchar* color; // a pixel from the input, "frame"
uchar* painted; // a pixel from the output, "painted"
// this draws a rectangle from pt4 to pt5 with the color
// specified by the three RGB values in the CV_RGB macro
// the R, G, and B channels are all 0 to 255...
// see the "this is insane!" caution below in order to
// use graphics on the live video stream...
cvRectangle(f_p, pt4, pt5, CV_RGB(0,0,255), 1); // 1 == thickness
// cvLine(f_p, pt4, pt5,CV_RGB(0,255,0),1,8); // 1 == thickness, 8 = connectedness
// This loops through the pixels in the rectangle specified
// by pt4 and pt5 (see setGlobals for their corners)
int xlow = (int)mymin(pt4.x,pt5.x);
int xhi = (int)mymax(pt4.x,pt5.x);
int ylow = (int)mymin(pt4.y,pt5.y);
int yhi = (int)mymax(pt4.y,pt5.y);
// Start doing stuff here.
// Parameters.
int samplerate = 1;
double mouldingthresh = 0.2;
bool failed;
int xstart, ystart, xend, yend;
int numsamples = (xhi-xlow)/samplerate + 1;
int* yminvals = new int[numsamples];
int* ymaxvals = new int[numsamples];
int xentry = 0;
int numreds = 0;
int numcreds = 0; // The number of reds found in a row in the center of the picture
int tempnumcreds = 0; // The current maximum number of reds in a row
int xcenter = xlow + (xhi-xlow)/2; // x coordinate for a vertical line through the center of the picture
for (int x = xlow; x<xhi; x++) //the x direction goes left to right
{
int ymax = -1;
int ymin = yhi + 1;
for (int y = ylow; y<yhi; y++) //the y direction goes top to bottom
{
// this is insane!!!
// unfortunately, access to the pixels is different depending on
// the source of the pixels: static images and video reverse their
// y orientations
// we handle this here...
int realy = y;
if (getImageAgainFromFile || getImageFromFile)
{
realy = imageSize.height - realy; // reverse if static image
}
// note that we need to use "realy" in each of these cases
color = cvPtr2D(frame,realy,x); // get the pixel we care about
painted = cvPtr2D(f_p,realy,x); // get the pixel we (might) change
r = (int)(color[2]); // the red component of the pixel we care about
g = (int)(color[1]); // the green component of the pixel we care about
b = (int)(color[0]); // the blue component of the pixel we care about
// you might want to call this here!
RGBtoHSV(r,g,b,&hue,&sat,&val);
// gratuitous drawing routine, just to show how it works
if (isRed(hue,sat,val))
{
painted[0] = blueValue; // sets blue to 255
if (x % samplerate == 0)
{
if(ymin > realy)
{
ymin = realy;
}
if(ymax < realy)
{
ymax = realy;
}
}
painted[1] = 0; // sets green to 0
painted[2] = 0; // sets red to 0
}
// This if statement figures out the number of reds in a row through the center of the picture.
if(x == xcenter)
{
if (isRed(hue, sat, val))
{
++tempnumcreds;
if(tempnumcreds > numcreds)
{
numcreds = tempnumcreds;
}
}
else
{
tempnumcreds = 0;
}
}
}
if (x % samplerate == 0)
{
if(ymax > -1)
{
numreds++;
}
yminvals[xentry] = ymin;
ymaxvals[xentry] = ymax;
xentry++;
if (ymax > -1)
{
// Mark those two points green.
uchar* yminpt = cvPtr2D(f_p,ymin,x); // get the ymin point
uchar* ymaxpt = cvPtr2D(f_p,ymax,x); // get the ymin point
yminpt[0] = 0;
yminpt[1] = 255;
yminpt[2] = 0;
ymaxpt[0] = 0;
ymaxpt[1] = 255;
ymaxpt[2] = 0;
}
}
}
// If we found more than the threshold value of reds in a row in the
// center of the picture, we detected a red molding through the center.
// Draw a vertical line through the center.
if(numcreds > numInCenter)
{
// cout << "Center line is getting drawn\n";
CvPoint top, bottom;
top.x = xcenter;
top.y= ylow;
bottom.x = xcenter;
bottom.y = yhi;
cvLine(f_p, top, bottom, CV_RGB(128,128,255),2,8); // 1 == thickness, 8 = connectedness
}
// Clearly, if we haven't found anything red in some portion of the
// samples, we've failed to have a red moulding anywhere around.
if( (((double) numreds)/numsamples) < mouldingthresh)
{
failed = true;
return; // nothing to draw, life sucks
}
// cvCircle( f_p, pt4, 10, CV_RGB(255,255,0), /*thickness*/ 1 );
// Otherwise, we must find the red line. For now, we assume there are
// no other large red objects in our picture.
// So, we just figure out the starting position of the red line (first
// n x in a row which have red), and then average all the y positions
// for the starting y. Repeat from the other end to find the end of
// the red line. Note: Victoria feels that this detection method may
// have problems in practice.
int numinrow = 10;
bool foundstart = false;
bool foundend = false;
for(int i = 0; (i < numsamples-numinrow) && !foundstart; ++i)
{
int numfoundinrow = 0;
for(int j = 0; j < numinrow; j++)
if(yminvals[j+i] > -1)
{
numfoundinrow++;
}
if(numfoundinrow == numinrow)
{
foundstart = true;
}
}
if(!foundstart)
{
return; // failed to find enough columns containing
// red in a row to conclude we have a line
}
xstart = i*samplerate;
ystart = 0;
yend = 0;
for(int k = 0; k<numinrow; k++)
{
ystart += yminvals[i+k] + ymaxvals[i+k];
}
ystart = ystart/(numinrow*2);
for(int i = numsamples-1; (i > numinrow) && !foundend; --i)
{
int numfoundinrow = 0;
for(int j = 0; j > -numinrow; j--)
if(yminvals[j+i] > -1)
{
numfoundinrow++;
}
if(numfoundinrow == numinrow)
{
foundend = true;
}
}
if(!foundend)
{
return; // This should never happen, because we found that many
// in a row before, but for sanity's sake . . .
}
cvCircle( f_p, pt3, 10, CV_RGB(255,255,0), /*thickness*/ 1 );
xend = i*samplerate;
for(int k = 0; k > -numinrow; k--)
{
yend += yminvals[i+k] + ymaxvals[i+k];
}
yend = yend/(numinrow*2);
//cout << "I think the line goes from (" << xstart << ", " << ystart;
//cout << ") to (" << xend << ", " << yend << ")" << endl;
CvPoint start, end;
start.x = xstart + xlow;
start.y = ystart;
end.x = xend + xlow;
end.y = yend;
cvLine(f_p, start, end,CV_RGB(255,128,255),2,8); // 1 == thickness, 8 = connectedness
delete[] yminvals;
delete[] ymaxvals;
}
void setGlobals()
{
// mouse click locations (old and new, to tell if we've
// clicked on a new point
old_click_pt.x = 0;
old_click_pt.y = 0;
new_click_pt.x = 0;
new_click_pt.y = 0;
// in theory these should get deleted at the end of the program, too...
// this is the calibration matrix of the camera
M = new float[9];
M[0]= 393.1788940f; M[1]= 0.0000000f; M[2]= 162.8373871f;
M[3]= 0.0000000f; M[4]= 395.7017517f; M[5]= 121.8078156f;
M[6]= 0.0000000f; M[7]= 0.0000000f; M[8]= 1.0000000f;
// these are the distortion parameters of the camera
D = new float[4];
D[0]=-0.358375f;
D[1]=0.168058f;
D[2]=-0.006497f;
D[3]=0.001283f;
// theseimage sizes are hard-coded, but should probably be obtained for each
// image individually -- however, with our cameras and images, this is safe.
imageSize.width = 320; imageSize.height = 240;
// set up some global points for drawing, etc.
int margin = 12;
pt1.x = margin; pt1.y = margin;
pt2.x = imageSize.width-margin; pt2.y = imageSize.height-margin;
pt3.x = imageSize.width/2;
pt3.y = imageSize.height/2;
pt4.x = 80;
pt4.y = 12;
pt5.x = 240;
pt5.y = 228;
pt6.x = 92;
pt6.y = 24;
pt7.x = 228;
pt7.y = 216;
}
syntax highlighted by Code2HTML, v. 0.9.1