Troy Boswell
unread,Jul 5, 2012, 11:52:50 AM7/5/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to openk...@googlegroups.com
I still have an issue with libfreenect dropping frames which results in sporadic response times of the kinect frames.
I have stopped using the C++ wrapper and I am using the glview example, I have tweeked it for opencv so that I had two separate threads, the main and freenect thread. However if I still block the main thread libfreenect drops frames like crazy. The problem is independent of opencv as I commented out all opencv calls and used getchar() to block main. I have also modified the freenect thread priority level to give it a much greater priority (i tried 20, 30 ,40 , 50) to call freenect_process_events(), however still no luck.
I know that my code works, because if main runs without any blocking frames aren't dropped and the response is very good, but it comes at the cost of running at about 80-90% cpu utilization which is not ideal.
What I wish to do is block main waiting for a ethernet packet and then process the received frames. To process these frames I have written my functionality using opencv.
I don't know the protocol for uploading code, but below are my functions if anyone is interested, I am thinking of giving the sync version a try, but I would ideally like to have full control:
The code is broken down as
-- 2xCallbacks
-- Kinect Thread
-- Main
-- 2xget frame functions
I haven't provided my global variables but I can, just thought the post would be long enough as it is.
Thankyou Troy
___________________________________________________________
// thread callbacks
void rgbCallback(freenect_device *dev, void *v_rgb, uint32_t timestamp){
// cout << "RGB callback" << std::endl;
pthread_mutex_lock(&rgbMutex);
videoTimestamp = timestamp;
rgb = (uint8_t*)v_rgb;
new_rgb_frame = true;
pthread_mutex_unlock(&rgbMutex);
}
void depthCallback(freenect_device *dev, void *v_depth, uint32_t timestamp){
// cout << "Depth callback" << std::endl;
pthread_mutex_lock(&depthMutex);
depthTimestamp = timestamp;
depth = (uint16_t*)v_depth;
new_depth_frame = true;
pthread_mutex_unlock(&depthMutex);
}
void *kinectThreadFunction(void *arg){
freenect_set_led(kinectDevice,LED_GREEN);//LED_RED);
freenect_set_video_callback(kinectDevice,rgbCallback);
freenect_set_depth_callback(kinectDevice,depthCallback);
freenect_set_video_mode(kinectDevice,freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM,FREENECT_VIDEO_RGB));
freenect_set_depth_mode(kinectDevice,freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM,FREENECT_DEPTH_11BIT));
freenect_start_video(kinectDevice);
freenect_start_depth(kinectDevice);
while(!die&& (freenect_process_events(kinectContext) >= 0)){
}
cout << "kinect shutting down" << endl;
freenect_stop_video(kinectDevice);
freenect_stop_depth(kinectDevice);
freenect_close_device(kinectDevice);
freenect_shutdown(kinectContext);
cout << "kinect shutdown" << endl;
die = true;
}
int main() {
int RVAL;
char key;
depthImg = cvCreateImage(cvSize(640,480),16,1);
rgbImg = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
IplImage *rbgFrame = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
IplImage *depthFrame = cvCreateImage(cvSize(640,480),16,1);
rgb = (uint8_t*)malloc(640*480*3);
depth = (uint16_t*)malloc(640*480);
if(freenect_init(&kinectContext,NULL) < 0){
cout<<"freenect initialisation failed!!"<<endl;
return 1;
}
// freenect_set_log_level(kinectContext, FREENECT_LOG_DEBUG);
freenect_select_subdevices(kinectContext,(freenect_device_flags)(FREENECT_DEVICE_CAMERA|FREENECT_DEVICE_MOTOR));
if( freenect_num_devices(kinectContext) < 1){
cout<<"No Device Present!!" << endl;
return 1;
}
if(freenect_open_device(kinectContext,&kinectDevice,0) < 0){
cout<<"Could Not Open Device!!"<< endl;
}
RVAL = pthread_create(&kinectThread,&kinectThreadAttr,kinectThreadFunction,NULL);
if(RVAL){
cout<<"pthread create failed"<<endl;
freenect_shutdown(kinectContext);
return 1;
}
uint32_t vid,dep;
while(!die){
cout<<"RGB ID = "<< vid <<"DEPTH ID = "<< dep<<endl;
getVideo(rbgFrame,&vid);
getDepth(depthFrame,&dep);
cvShowImage("RGB", rbgFrame);
cvShowImage("DEPTH", depthFrame);
cvWaitKey(1);
key = getchar();
if(key == 27){
die = true;
}
}
pthread_join(kinectThread,NULL); // wait for kinect thread to die
cout << "Exiting"<< endl;
return 0;
}
bool getVideo(IplImage *output,uint32_t *frameID) {
pthread_mutex_lock(&rgbMutex);
if(new_rgb_frame) {
cvSetData(rgbImg, rgb, 640*3);
cvCvtColor(rgbImg, output, CV_RGB2BGR);
cvCopy(rgbImg,output);
*frameID = videoTimestamp;
new_rgb_frame = false;
pthread_mutex_unlock(&rgbMutex);
return true;
} else {
pthread_mutex_unlock(&rgbMutex);
return false;
}
}
bool getDepth(IplImage *output,uint32_t *frameID) {
pthread_mutex_lock(&depthMutex);
if(new_depth_frame) {
cvSetData(depthImg, depth, depthImg->widthStep);
cvCopy(depthImg,output);
*frameID = depthTimestamp;
new_depth_frame = false;
pthread_mutex_unlock(&depthMutex);
return true;
} else {
pthread_mutex_unlock(&depthMutex);
return false;
}
}