/****************************************************************************** * Webcam support for Mathematica through opencv * * This MathLink program tries to open a webcam connected to the pc * through the opencv library. If this succeeds it shows a live image * and provides a Mathematica function CatchFrame[] which transfers * a snapshot of the current frame to Mathematica. * Furthermore there is a GetCameraProps[] function which returns some * properties of the used camera. * * This file was originally written by Jens-Peer Kuska and later adapted by * Patrick Scheibe. * * Compilation: * Convert the tm file into a cpp file by * ${MROOT}/mprep MathCam.tm > MathCam.cpp * * Here and below ${MROOT} is a environment variable containing the correct * path to the MathLink CompilerAdditions in the Mathematica install path. * On my machine this is for instance: * * /usr/local/Wolfram/Mathematica/8.0/SystemFiles/Links/MathLink/\ * DeveloperKit/Linux-x86-64/CompilerAdditions * * Next step is to compile the source with a cpp compiler. The comandline * consists basically of two sets of options. The first are the options for * MathLink which can be looked up in the documentation. The second are the * required libraries for opencv which can be extracted with * `pkg-config --cflags --libs opencv`. The resulting commandline should look * like this: * * g++ -I${MROOT} -L${MROOT} -lm -lpthread -lrt -lstdc++ -lML64i3 \ * $(pkg-config --cflags --libs opencv) -o MathCam MathCam.cpp * * This program can now used inside Mathematica. Connect your webcam to your * pc and type in Mathematica * * lnk = Install["/your/correct/path/MathCam"] * * and if a webcam window opens, you can try CatchFrame[]. * * Have fun, Patrick. */ #include #include #include "mathlink.h" #include #include CvCapture *capture = 0; IplImage *frame = 0; MLINK mlink; int err; int main(int argc, char** argv) { if(!stdenv) stdenv = MLInitialize( (char *)0); if(stdenv == (MLENV) 0) { return !MLDone; } if(!stdhandler) stdhandler = MLCreateMessageHandler(stdenv, NewMLHandlerProc( MLDefaultHandler), 0); #if defined(WINDOWS_MATHLINK) if(!stdyielder) stdyielder = MLCreateYieldFunction( stdenv, NewMLYielderProc( MLDefaultYielder), 0); #endif mlink = MLOpenArgv( stdenv, argv, argv + argc, &err); if( mlink == (MLINK)0){ MLAlert( stdenv, MLErrorString( stdenv, err)); MLClose(mlink); if(stdenv) MLDeinitialize( stdenv); stdenv = (MLEnvironment)0; exit(0); } #if defined(WINDOWS_MATHLINK) if( MLInstance){ if(stdyielder) MLSetYieldFunction(mlink, stdyielder); if(stdhandler) MLSetMessageHandler(mlink, stdhandler); } #endif if(!MLInstall( mlink)) { MLClose(mlink); if(stdenv) MLDeinitialize( stdenv); stdenv = (MLEnvironment)0; exit(0); } capture=cvCaptureFromCAM(0); if(!capture){ fprintf(stderr,"Error initializing camera.\n"); MLClose(mlink); if(stdenv) MLDeinitialize( stdenv); stdenv = (MLEnvironment)0; exit(0); } cvNamedWindow("MathCam",0); for(;;){ frame = cvQueryFrame(capture); if(!frame) exit(0); cvWaitKey(10); cvShowImage("MathCam",frame); int pkt; if(MLDone && MLError(mlink)) { cvReleaseCapture( &capture ); cvDestroyWindow("MathCam"); return 0; } while(MLReady(mlink) && !MLDone) { pkt=MLNextPacket(mlink); MLAbort = 0; if(RESUMEPKT == pkt || ILLEGALPKT == pkt) { MLClose(mlink); if(stdenv) MLDeinitialize( stdenv); stdenv = (MLEnvironment)0; exit(0); cvReleaseCapture( &capture ); cvDestroyWindow("MathCam"); } fprintf(stderr,"3"); if(pkt != CALLPKT || !MLDoCallPacket(mlink)) return 0; MLFlush(mlink); MLAbort = 0; } } return 0; } :Begin: :Function: getCameraProps :Pattern: GetCameraProps[] :Arguments: {} :ArgumentTypes: {} :ReturnType: Manual :End: void getCameraProps(void){ double w,h,bright,contrast,saturation,hue; w = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH ); h = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT); bright = cvGetCaptureProperty(capture, CV_CAP_PROP_BRIGHTNESS); contrast = cvGetCaptureProperty(capture, CV_CAP_PROP_CONTRAST); saturation = cvGetCaptureProperty(capture, CV_CAP_PROP_SATURATION); hue = cvGetCaptureProperty(capture, CV_CAP_PROP_HUE); MLPutFunction(stdlink, "List", 6); MLPutFunction(stdlink,"Rule",2); MLPutString(stdlink,"Width"); MLPutInteger(stdlink,w); MLPutFunction(stdlink,"Rule",2); MLPutString(stdlink,"Height"); MLPutInteger(stdlink,h); MLPutFunction(stdlink,"Rule",2); MLPutString(stdlink,"Brightness"); MLPutReal(stdlink,bright); MLPutFunction(stdlink,"Rule",2); MLPutString(stdlink,"Contrast"); MLPutReal(stdlink,contrast); MLPutFunction(stdlink,"Rule",2); MLPutString(stdlink,"Saturation"); MLPutReal(stdlink,saturation); MLPutFunction(stdlink,"Rule",2); MLPutString(stdlink,"Hue"); MLPutReal(stdlink,hue); } :Begin: :Function: catchFrame :Pattern: CatchFrame[] :Arguments: {} :ArgumentTypes: {} :ReturnType: Manual :End: void catchFrame(void){ if(!frame){ MLPutSymbol(stdlink,"$Failed"); return; } long dims[3],size,mu; int *bm; dims[0]=frame->height; dims[1]=frame->width; dims[2]=frame->nChannels; size=dims[0]*dims[1]; mu=size*dims[2]; bm=new int[mu]; for(long i=0; iimageData[3*i+2]; bm[3*i+1]=(unsigned char)frame->imageData[3*i+1]; bm[3*i+2]=(unsigned char)frame->imageData[3*i]; } MLPutFunction(stdlink,"Image",2); MLPutIntegerArray(stdlink,bm,dims,NULL,3); MLPutString(stdlink,"Byte"); delete[] bm; }