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