From: Callum Date: Tue, 29 Oct 2013 13:14:02 +0000 (+0800) Subject: Done a bunch of changes to image handling X-Git-Url: https://git.ucc.asn.au/?p=matches%2FMCTX3420.git;a=commitdiff_plain;h=69d9f5d6774384f76c75248907304b0fbd66bbd1 Done a bunch of changes to image handling --- diff --git a/server/image.c b/server/image.c index 1d35264..3c30467 100644 --- a/server/image.c +++ b/server/image.c @@ -3,64 +3,73 @@ #include "image.h" #include #include +#include CvCapture *capture; int captureID = -1; void Image_Handler(FCGIContext * context, char * params) { - int num = 0, width = 800, height = 600; + int num = 0, width = 1600, height = 1200; // Set Default values FCGIValue val[] = { {"num", &num, FCGI_INT_T}, {"width", &width, FCGI_INT_T}, {"height", &height, FCGI_INT_T} }; - if (!FCGI_ParseRequest(context, params, val, 3)) + if (!FCGI_ParseRequest(context, params, val, 3)) // Populate val return; - else if (num < 0 || num > 1) { + // Ensure the camera id is 0 or 1. Even though we plan to only have 1 camera attached at a time, this will allow 2. increase + else if (num < 0 || num > 1) { FCGI_RejectJSON(context, "Invalid capture number"); return; + // Ensure valid widths } else if (width <= 0 || height <= 0) { FCGI_RejectJSON(context, "Invalid width/height"); return; } + + CvMat * g_src = NULL; // Source Image + CvMat * g_encoded; // Encoded Image - if (captureID != num) { - if (captureID >= 0) { - cvReleaseCapture(&capture); - } - capture = cvCreateCameraCapture(num); - captureID = num; - } + Camera_GetImage( num, width, height ,g_src); + g_encoded = cvEncodeImage("test_encode.jpg",g_src,0); + + Log(LOGNOTE, "Sending image!"); + FCGI_PrintRaw("Content-type: image/jpg\r\n"); + FCGI_PrintRaw("Cache-Control: no-cache, no-store, must-revalidate\r\n\r\n"); + //FCGI_PrintRaw("Content-Length: %d", g_encoded->rows*g_encoded->cols); + FCGI_WriteBinary(g_encoded->data.ptr,1,g_encoded->rows*g_encoded->cols); + + cvReleaseMat(&g_encoded); + cvReleaseMat(&g_src); +} + + bool Camera_GetImage(int num, int width, int height, CvMat * image) + { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Need to use a mutex to ensure 2 captures are not open at once + pthread_mutex_lock(&mutex); + bool result = false; + + capture = cvCreateCameraCapture(num); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height); - static int p[] = {CV_IMWRITE_JPEG_QUALITY, 100, 0}; - IplImage * frame = cvQueryFrame(capture); - assert(frame != NULL); - -// CvMat stub; - // CvMat * background = cvGetMat(frame, &stub, 0, 0); + if( frame == NULL) + return result; -// CvMat *cv8u = cvCreateMat(frame->width, frame->height, CV_8U); -// double min, max; -// CvPoint a,b; -// cvMinMaxLoc(background, &min, &max, &a, &b, 0); - -// double ccscale = 255.0/(max-min); -// double ccshift = -min; - //cvCvtScale(frame, cv8u, ccscale, ccshift); - CvMat * jpg = cvEncodeImage(".jpg", frame, p); + // Convert the IplImage pointer to CvMat + CvMat stub; + image = cvGetMat(frame, &stub, 0, 0); + if( image == NULL) + return result; - // Will this work? - Log(LOGNOTE, "Sending image!"); - FCGI_PrintRaw("Content-type: image/jpg\r\n"); - FCGI_PrintRaw("Cache-Control: no-cache, no-store, must-revalidate\r\n\r\n"); - //FCGI_PrintRaw("Content-Length: %d", jpg->rows*jpg->cols); - FCGI_WriteBinary(jpg->data.ptr,1,jpg->rows*jpg->cols); - - cvReleaseMat(&jpg); + // Release the capture and IplImage pointers cvReleaseImageHeader(&frame); + cvReleaseCapture(&capture); + + pthread_mutex_unlock(&mutex); //Close the mutex + return true; } + diff --git a/server/image.h b/server/image.h index 3c1ab69..7f4271d 100644 --- a/server/image.h +++ b/server/image.h @@ -7,10 +7,12 @@ #define _IMAGE_H #include "common.h" +#include "cv.h" extern void Image_Init(); extern void Image_Handler(FCGIContext * context, char * params); extern void Image_Cleanup(); +extern bool Camera_GetImage(int num, int width, int height, CvMat * image); #endif //_IMAGE_H diff --git a/server/sensors/dilatometer.c b/server/sensors/dilatometer.c index 0bbda6b..10b2e61 100644 --- a/server/sensors/dilatometer.c +++ b/server/sensors/dilatometer.c @@ -11,6 +11,10 @@ // test positions static double test_left, test_right; +// Remembers the last position to measure rate of expansion +static double lastPosition; + + // Canny Edge algorithm variables int blur = 5; int lowThreshold = 30; @@ -23,8 +27,8 @@ static CvMat * g_srcGray = NULL; // Gray scale of source image static CvMat * g_edges = NULL; // Detected Edges /** Pointers for capturing image **/ -static CvCapture * g_capture = NULL; -static IplImage * frame = NULL; // This is required as you can not use capture with CvMat in C +//static CvCapture * g_capture = NULL; +//static IplImage * frame = NULL; // This is required as you can not use capture with CvMat in C /** @@ -70,10 +74,11 @@ void Dilatometer_TestImage() */ bool Dilatometer_Cleanup(int id) { - if (g_capture != NULL) - cvReleaseCapture(&g_capture); - if (frame != NULL) - cvReleaseImageHeader(&frame); + //if (g_capture != NULL) + // cvReleaseCapture(&g_capture); + //if (frame != NULL) + // cvReleaseImageHeader(&frame); + //if (g_srcRGB != NULL) // cvReleaseMat(&g_srcRGB); // Causing run time error in cvReleaseMat if (g_srcGray != NULL) @@ -84,9 +89,9 @@ bool Dilatometer_Cleanup(int id) } /** - * Get an image from the Dilatometer + * Get an image from the Dilatometer. Replaced by Camera_GetImage in image.c */ -static bool Dilatometer_GetImage() +/*static bool Dilatometer_GetImage() { bool result = true; // If more than one camera is connected, then input needs to be determined, however the camera ID may change after being unplugged @@ -118,10 +123,13 @@ static bool Dilatometer_GetImage() cvCvtColor(g_srcRGB,g_srcGray,CV_RGB2GRAY); return result; -} +}*/ void CannyThreshold() { + // Convert the RGB source file to grayscale + cvCvtColor(g_srcRGB,g_srcGray,CV_RGB2GRAY); + if ( g_edges == NULL) { g_edges = cvCreateMat(g_srcGray->rows,g_srcGray->cols,CV_8UC1); @@ -152,7 +160,7 @@ void CannyThreshold() } /** - * Read the dilatometer image. The value changed will correspond to the new location of the edge. + * Read the dilatometer image. The value changed will correspond to the rate of expansion. If no edge is found then * @param val - Will store the read value if successful * @param samples - Number of rows to scan (increasing will slow down performance!) * @returns true on successful read @@ -162,11 +170,12 @@ bool Dilatometer_GetEdge( double * value, int samples) bool result = false; double average = 0; // Get the image from the camera - result = Dilatometer_GetImage(); + result = Camera_GetImage( 0, 1600, 1200 ,&g_srcRGB); // Get a 1600x1200 image and place it into src + // If an error occured when capturing image then return if (!result) return result; - + // Apply the Canny Edge theorem to the image CannyThreshold(); @@ -180,7 +189,7 @@ bool Dilatometer_GetEdge( double * value, int samples) } int sample_height; - int num_edges = 0; // Number of edges. if each sample location has an edge, then num_edges = samples + int num_edges = 0; // Number of edges found. if each sample location has an edge, then num_edges = samples for (int i=0; i 0) average /= num_edges; + else + return result; // As no edges were found if( average > 0) { - result = true; //Successfully found an edge - *value = average; + result = true; // Successfully found an edge + // If the experiment has already been initialised + if( lastPosition > 0) + { + // Find the rate of expansion and convert to mm. Will give a negative result for compression. + *value = (average - lastPosition) * SCALE; + lastPosition = average; // Current position now becomes the last position + } } return result; } @@ -238,8 +255,9 @@ bool Dilatometer_Init(const char * name, int id) { // Make an initial reading (will allocate memory the first time only). double val; - Dilatometer_GetEdge(&val, 1); - return true; + lastPosition = 0; // Reset the last position + bool result = Dilatometer_GetEdge(&val, 1); + return result; } // Overlays a line over the given edge position diff --git a/server/sensors/dilatometer.h b/server/sensors/dilatometer.h index 2c683d6..e8be7d1 100644 --- a/server/sensors/dilatometer.h +++ b/server/sensors/dilatometer.h @@ -11,6 +11,9 @@ //Number of samples of the image to take #define SAMPLES 600 +//Scaling factor required to change from pixels to mm +#define SCALE 1 // Note camera has not been calibrated yet so result will be in pixels + extern bool Dilatometer_Init(const char * name, int id); // Initialise the dilatometer extern bool Dilatometer_Cleanup(int id); // Cleanup extern bool Dilatometer_Read(int id, double * value); // Read the Dilatometer