teaching machines

Otolith Threshold and GUI

November 18, 2011 by . Filed under fish vision.

Winston and I made progress on thresholding the images and getting user input.

The currently committed version takes in a (hard coded) image path and displays the image with a binary threshold, with a check value of 90. In the GUI, there is a slider that allows the user to change the check value to any number between 0 and 255. The image is update in real time. Also, clicking and dragging on the image allows a red line to be drawn across the image. Currently, we limit the user to only one drawing attempt.

The threshold approach works fairly well for lines farther from the center, but quality begins to deteriorate as you move in. We have yet to use the line to calculate the number of rings drawn over and the distances between them.

Here is the current code:

#include <cv.h>
#include <highgui.h>

bool drawingLine,once;
CvPoint p1, p2;
int threshold;

void get_Threshold(IplImage* src, IplImage* dst){
	// Allocate individual image planes
	IplImage* r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
	IplImage* g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);
	IplImage* b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U, 1);

	//Split image on the color plane
	cvSplit(src,r,g,b,NULL);

	//Temporary storage
	IplImage* s = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);

	//Add equally weighted rgb values
	cvAddWeighted(r, 1./3., g, 1./3., 0.0, s);
	cvAddWeighted(s, 2./3., b, 1./3., 0.0, s);

	//Threshold
	cvThreshold(s,dst,threshold,255,CV_THRESH_BINARY);

	cvReleaseImage(&r);
	cvReleaseImage(&g);
	cvReleaseImage(&b);
	cvReleaseImage(&s);
}

void my_mouse_callback(int event, int x, int y, int flags, void* img){
	IplImage* image = (IplImage*) img;

	switch(event){
	//Update endpoint if the line is being drawn. Only allow one line.
	case CV_EVENT_MOUSEMOVE:{
		if(drawingLine && !once){
			p2 = cvPoint(x,y);
		}
	}
	break;		
	//Set the line points and start drawing as long as we haven't already
	//drawn a line
	case CV_EVENT_LBUTTONDOWN:{
		if(!once){
		drawingLine = true;
		p1 = cvPoint(x,y);
		p2 = cvPoint(x,y);
		}
	}
	break;
	//and the line and prevent future lines from being drawn
	case CV_EVENT_LBUTTONUP:{
		if(!once){
		p2 = cvPoint(x,y);
		drawingLine = false;
		}
		once = true;
	}
	break;
	}

}
//update the image threshold from trackbar
void on_change(int pos){
	threshold = pos;
}

int main(int argc, char **argv)
{	//initialize
	threshold = 90;
	IplImage* img = cvLoadImage("C:\\Users\\Corey\\Pictures\\Fish_Research\\FCM060-2fL.jpeg");
	IplImage* dst = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U, 1);
	drawingLine = false;
	once = false;

	//Holds the tresholded image
	IplImage* thresholdGray = cvCreateImage(cvGetSize(dst),IPL_DEPTH_8U,1);
	//holds the color version of the thresholded image so color lines can be drawn on top
	IplImage* thresholdColor = cvCreateImage(cvGetSize(dst),IPL_DEPTH_8U,3);

	//create the gui
	cvNamedWindow("Otolith",0);
	cvMoveWindow("Otolith",0,0);
	cvResizeWindow("Otolith",cvGetSize(img).width,cvGetSize(img).height);
	cvCreateTrackbar("Threshold","Otolith",&threshold,255,on_change);
	cvSetMouseCallback("Otolith",my_mouse_callback, (void*)dst); 
	//run until user hits Esc
	while(1){
		//threshold the image
		get_Threshold(img,thresholdGray);

		//create the colored version
		cvMerge(thresholdGray,thresholdGray,
                        thresholdGray,NULL,thresholdColor);

		//draw the line if needed
		if(drawingLine || once){
			cvLine(thresholdColor,p1,p2,CV_RGB(255,0,0),2,8,0);
		}

		//show the image
		cvShowImage("Otolith", thresholdColor);
		
		//check for key press
		if(cvWaitKey(15)==27) break;
	}
	cvReleaseImage(&img);
	cvReleaseImage(&dst);
	cvReleaseImage(&thresholdGray);
	cvReleaseImage(&thresholdColor);
	cvDestroyWindow("Otolith");
	return 0;
}