Ask Your Question

Revision history [back]

Memory leak in the sample code to capture image with Opencv with GLIB

I am pretty new to camera sort of drivers and trying to explore the best available options in capturing a IMAGE from a webcam.

I indeed have specs like the APP needs to cross platform & use front cam to capture image.

To start this development process i used openCV to capture image. However, when multiple cameras are connected to the system.

To implement camera functionality here is the sample code i have built.

I see some memory leak in code when capturing continuous image with openCv. Unable to find the cause.

/*
 ============================================================================
 Name        : cameraLibSam.c
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <opencv/highgui.h>
#include <glib.h>
//#include "libuvc/libuvc.h"
#include <stdio.h>
#include <windows.h>
#include <libusb-1.0/libusb.h>
#include <conio.h>

#include <opencv2/core/core_c.h>
#include <opencv2/highgui/highgui_c.h>
#include <opencv/cv.h>

#define SET 1
#define GET 0


GHashTable* cameraTable;

debug_log(char *data,int level){
    printf("%s",data);
}
typedef struct
{
    char cmd;
    int width;
    int height;
    int brightness;
    int contrast;
    int saturation;
    int gain;
    int quality;
    char file[20];
    char device[20];
    char nextcmd[20];
    int delay;
}camera_dev_t;

int process_camera (camera_dev_t *settings);

int printdev(libusb_device *dev, char *devId); //prototype of the function

 //TODO static const char version[] = VERSION;
 int run = 1;
 char temp[256];

char getCameraModel(void);

static CvCapture* capture;

void freeVals(gpointer key, gpointer value,gpointer user_data)
{
    printf("Key : %s --> Value : %s\n",key,value);
    free(key);
    free(value);
}

void printKeys(gpointer key, gpointer value,gpointer user_data)
{
    printf("Key : %s --> Value : %s\n",key,value);
}
int getcameraConfigurationInfo()
{
    GKeyFile *key_file;
    GError *error;
    gint keyCount;
    gsize num_keys;
    gchar **keys;
    gchar *value;

    key_file = g_key_file_new();
    error = NULL;
    if(!g_key_file_load_from_file(key_file,"config.ini",
            G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                                  &error))
    {
         g_debug("%s", error->message);
         return -1;
    }

        if(g_key_file_has_group(key_file,"PROVIEW"))
        {
            keys = g_key_file_get_keys(key_file,"PROVIEW",&num_keys,&error);
            printf("dd NUMKEY %d\n",num_keys);
            int len=0;
                for(keyCount = 0;keyCount < num_keys;keyCount++)
                {
                    value=g_key_file_get_string(key_file,"PROVIEW",keys[keyCount],&error);
                    if(strstr(keys[keyCount],"Priority") != NULL)
                    {
                        len = strlen(value) + 9;
                        char *charVal = (char *)malloc(len);
                        memset(charVal,0,sizeof(charVal));
                        sprintf(charVal,"PROVIEW%s", value);
                        char *charKey = (char *)malloc(strlen(keys[keyCount])+9);
                        sprintf(charKey,"PROVIEW%s", keys[keyCount]);
                        g_hash_table_insert(cameraTable, charKey, charVal);
                        //if(value !=NULL)
                            //free(value);\
                        if (value)
                        //g_strfreev(value);
                    }
                    else
                    {
                        len = strlen(keys[keyCount]) + 9; //adding groupName ref + 1 byte extra for NULL
                        char *charKey = (char *)malloc(len);
                        char *charVal = (char *)malloc(strlen(value)+1);
                        memset(charKey,0,sizeof(charKey));
                        sprintf(charKey,"PROVIEW%s", keys[keyCount]);
                        memset(charVal,0,sizeof(charVal));
                        strcpy(charVal,value);
                        //sprintf(charVal,"PROVIEW%s", keys[keyCount]);
                        g_hash_table_insert(cameraTable, charVal, charKey);
                    }
                }
            g_hash_table_foreach(cameraTable,(GHFunc)  printKeys,NULL);
            g_strfreev(keys);
        }
        else
        {
            printf("Group not found %d\n",0);
            g_key_file_free(key_file);
            return -1;
        }
    g_key_file_free(key_file);
    return 0;
}

int printdev(libusb_device *dev,char *devId) {
    int i = 0;
    struct libusb_device_descriptor desc;
    int r = libusb_get_device_descriptor(dev, &desc);
    if (r < 0) {
        printf("failed to get device descriptor\n");
        return -2;
    }
    if((int)desc.bDeviceClass== 239){
        sprintf(devId,"%04X,%04X",desc.idVendor,desc.idProduct);
        printf("Number of possible configurations: %d\n",(int)desc.bNumConfigurations);
        printf("Device Class: %d\n",(int)desc.bDeviceClass);
        printf("VendorID: %04X\n",desc.idVendor);
        printf("ProductID: %04X\n",desc.idProduct);
    }
    else
        i=-1;
    return i;
}

int getConnectedCamID()
{
        char *priorityCam;
        char devId[32] = {'\0'};
        int camId=-1;
        libusb_device **devs;
        libusb_context *ctx = NULL;
        int r;
        ssize_t cnt;
        r = libusb_init(&ctx);
        if(r < 0)
        {
            printf("Init Error \n");
            return 1;
        }
        libusb_set_debug(ctx, 3);
        cnt = libusb_get_device_list(ctx, &devs);
        if(cnt < 0)
        {
            printf("Get Device Error"); //there was an error
        }
        printf(" Devices in list. %d",cnt); //print total number of usb devices
        ssize_t i; //for iterating through the list
        priorityCam=g_hash_table_lookup(cameraTable,"PROVIEWPriority");

        for(i = 0; i < cnt; i++)
        {
            char *devInfo;
            int isCam=-1;
            memset(devId,0,sizeof(devId));
            isCam=printdev(devs[i],devId); //print specs of this device
            if(devId != NULL && isCam == 0 )
            {

                camId++;
                devInfo=g_hash_table_lookup(cameraTable,devId);
                if(devInfo != NULL)
                {
                    printf("Camid : %d : Model: %s : pri with %s\n",camId,devInfo ,priorityCam);

                        if((strstr(devInfo,priorityCam)!=NULL) && priorityCam != NULL)
                        {
                            /*if(strstr(devInfo,priorityCam)!=NULL)
                            {
                                camId=i;
                                break;
                            }*/
                            printf("Expected break:\n");
                            break;
                        }

                }

            }


        }
        libusb_free_device_list(devs, 1); //free the list, unref the devices in it
        libusb_exit(ctx); //close the session
        return camId;
}

int cameraSettingParameters(CvCapture* capture,camera_dev_t *settings,int parameter)
{
    //CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
    switch(parameter)
    {
    case GET:
        settings->contrast=cvGetCaptureProperty (capture, CV_CAP_PROP_CONTRAST);
        settings->brightness=cvGetCaptureProperty (capture, CV_CAP_PROP_BRIGHTNESS);
        settings->saturation=cvGetCaptureProperty (capture, CV_CAP_PROP_SATURATION);
        settings->gain=cvGetCaptureProperty (capture, CV_CAP_PROP_GAIN);
        settings->width=cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH);
        settings->height=cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT);
        break;
    case SET:
        if(settings->contrast)
            settings->contrast=cvSetCaptureProperty (capture, CV_CAP_PROP_CONTRAST,settings->contrast);
        if(settings->brightness)
            settings->brightness=cvSetCaptureProperty (capture, CV_CAP_PROP_BRIGHTNESS,settings->brightness);
        if(settings->saturation)
            settings->saturation=cvSetCaptureProperty (capture, CV_CAP_PROP_SATURATION,settings->saturation);
        if(settings->gain)
            settings->gain=cvSetCaptureProperty (capture, CV_CAP_PROP_GAIN,settings->gain);
        if(settings->width)
            settings->width=cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH,settings->width);
        if(settings->height)
            settings->height=cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT,settings->height);
        break;
    default:
        break;
    }
    return 0;

}

int captureImageFromCam(int camId,camera_dev_t *settings)
{
    IplImage* frame;
    int result;
    char outputfile[128] = {'\0'};
    strcpy(outputfile,&settings->file);
    CvCapture* capture = cvCaptureFromCAM(camId); //Capture using any camera connected to your system
    if ( capture == NULL) {
        debug_log("PERIPHERAL:CAMERA:capture is NULL so creating",1);
        //capture = cvCaptureFromCAM(CV_CAP_ANY); //Capture using any camera connected to your system
        return -1;
    }
    cameraSettingParameters(capture,settings,SET);

    int i = 10 ;
    debug_log("PERIPHERAL:CAMERA: capture under progress",1);
    while(i!=0){ //Create infinte loop for live streaming
        frame = cvQueryFrame(capture); //Create image frames from capture
        Sleep(20);
        i--;
    }
    debug_log("PERIPHERAL:CAMERA: capture END",1);
    sprintf(temp, "save image start value of cvSaveImage: %d with FILENAME: %s\n", 0,outputfile);
    debug_log(temp,1);
    result = cvSaveImage(outputfile, (CvArr *)frame,0);
    sprintf(temp, "return value of cvSaveImage: %d with FILENAME: %s\n", result,outputfile);
    debug_log(temp,1);
    if(capture != NULL){
        cvReleaseCapture(&capture);
    }
    return 0;
}


int main() {
    camera_dev_t settings;
    cameraTable = g_hash_table_new_full (g_str_hash, g_str_equal,free,free);
    memset(&settings,0,sizeof(camera_dev_t));
    settings.cmd = 'I';
    int ret = 0;
    int i = 0 ;



        ret = getcameraConfigurationInfo();
        printf("Camera Config status : %d",ret);

        ret = getConnectedCamID();
        printf("Camera getConnectedCamID status : %d",ret);
        for( i =0; i < 25 ; i++)
        {

        sprintf(settings.file,"testing%d.jpg",i);
        printf("Image capture for device id : %d",ret);
        captureImageFromCam(ret,&settings);
        Sleep(10*1000);
    }

            g_hash_table_destroy(cameraTable);  
    return 0;
}

config.ini

[PROVIEW]
Priority=CAM2
CAM1=0C45,6340
CAM2=046D,0825

Also noticed my thread count is getting increased when each time loop is executed