Saturday 2 March 2013

Getting Started with OpenCV

I am starting work on the video version of my Epileptic Seizure detector project, while I wait for a very sensitive microphone to arrive off the slow boat from China, which I will use for the Audio version.

I am using the OpenCV computer vision library.  What I am hoping to do is to either:

  • Detect the high frequency movement associated with a seizure, or
  • Detect breathing (and raise an alarm if it stops)
This seems quite similar to the sort of things that MIT have demonstrated some success with last year (http://people.csail.mit.edu/mrub/vidmag/).   Their code is written in Matlib, which is a commercial package, so not much use to me, so I am looking at doing something similar in OpenCV.

But first things first, I need to get OpenCV working.  I am going to use plain old C, because I know the syntax (no funny '<'s in the code that you seem to get in C++).  I may move to Python if I start to need to plot graphs to understand what is happening, so I can use the matplotlib graphical library.

I am using CMake to sort out the make file.  I really don't know how this works - I must have found a tutorial somewhere that told me to create a file called CMakeLists.txt.  Mine looks like:
cmake_minimum_required(VERSION 2.8)
PROJECT( sd )
FIND_PACKAGE( OpenCV REQUIRED )
ADD_EXECUTABLE( sd Seizure_Detector.c )
TARGET_LINK_LIBRARIES( sd ${OpenCV_LIBS} )
Running 'cmake' creates a standard Makefile, and then typing 'make' will compile Seizure_Detector.c and link it into an executable called 'sd', including the OpenCV libraries.   Seems quite clever.

The program to detect a seizure is going to have to look for changes in a series of images in a certain frequency range (a few Hz I think).   To detect this I will need to collect a series of images, process them, and do some sort of Fourier transform to detect the frequency components.

So to get started, grab an image from the networked camera.  This seems to work:
IplImage *origImg = 0;
char *window1 = "Original";
int main() {
    camera = cvCaptureFromFile("rtsp://192.168.1.18/live_mpeg4.sdp");
    if(camera!=NULL) {
    cvNamedWindow(window1,CV_WINDOW_AUTOSIZE);
    while((origImg=cvQueryFrame(camera)) != NULL) {
      procImg = cvCreateImage(cvGetSize(origImg),8,1);
      cvShowImage(window1,origImg);
    }
}
}

I can also smooth the image, and do some edge detection:

    while((origImg=cvQueryFrame(camera)) != NULL) {
      procImg = cvCreateImage(cvGetSize(origImg),8,1);
      cvCvtColor(origImg,procImg,CV_BGR2GRAY);
      //cvSmooth(procImg, procImg, CV_GAUSSIAN_5x5,9,9,0,0);
      smoothImg = cvCreateImage(cvGetSize(origImg),8,1);
      cvSmooth(procImg, smoothImg, CV_GAUSSIAN,9,9,0,0);
      cvCanny(smoothImg,procImg,0,20,3);
   
      cvShowImage(window1,origImg);
      cvShowImage(window2,procImg);
}

Full code at https://github.com/jones139/arduino-projects/tree/master/seizure_detector/video_version.

I am about to update the code to maintain a set of the most recent 15 images (=1 second of video), so I can do some sort of time series analysis on it to get the frequencies.....


No comments: