bool ReadImageSequenceToVolumeDatum(const char* img_dir, const int start_frm, const int label, const int length, const int height, const int width, const int sampling_rate, VolumeDatum* datum){ char fn_im[256]; cv::Mat img, img_origin; char *buffer = NULL; int offset = 0; int channel_size = 0; int image_size = 0; int data_size = 0; datum->set_channels(3); datum->set_length(length); datum->set_label(label); datum->clear_data(); datum->clear_float_data(); offset = 0; int end_frm = start_frm + length * sampling_rate; for (int i=start_frm; i<end_frm; i+=sampling_rate){ sprintf(fn_im, "%s/%06d.jpg", img_dir, i); if (height > 0 && width > 0) { img_origin = cv::imread(fn_im, CV_LOAD_IMAGE_COLOR); if (!img_origin.data) { LOG(ERROR) << "Could not open or find file " << fn_im; return false; } cv::resize(img_origin, img, cv::Size(width, height)); img_origin.release(); } else { img = cv::imread(fn_im, CV_LOAD_IMAGE_COLOR); } if (!img.data){ LOG(ERROR) << "Could not open or find file " << fn_im; return false; } if (i==start_frm){ datum->set_height(img.rows); datum->set_width(img.cols); image_size = img.rows * img.cols; channel_size = image_size * length; data_size = channel_size * 3; buffer = new char[data_size]; } for (int c=0; c<3; c++){ ImageChannelToBuffer(&img, buffer + c * channel_size + offset, c); } offset += image_size; } CHECK(offset == channel_size) << "wrong offset size" << std::endl; datum->set_data(buffer, data_size); delete []buffer; return true; }
bool ReadVideoToVolumeDatumHelperSafe(const char* filename, const int start_frm, const int label, const int length, const int height, const int width, const int sampling_rate, VolumeDatum* datum){ cv::VideoCapture cap; cv::Mat img, img_origin; char *buffer = NULL; int offset = 0; int channel_size = 0; int image_size = 0; int data_size = 0; int use_start_frm = start_frm; cap.open(filename); if (!cap.isOpened()){ LOG(ERROR) << "Cannot open " << filename; return false; } datum->set_channels(3); datum->set_length(length); datum->set_label(label); datum->clear_data(); datum->clear_float_data(); int num_of_frames = cap.get(CV_CAP_PROP_FRAME_COUNT); if (num_of_frames<length*sampling_rate){ LOG(INFO) << filename << " does not have enough frames; having " << num_of_frames; return false; } if (start_frm < 0){ use_start_frm = caffe_rng_rand()%(num_of_frames-length*sampling_rate+1); } offset = 0; CHECK_GE(use_start_frm, 0) << "start frame must be greater or equal to 0"; // Instead of random acess, do sequentically access (avoid key-frame issue) // This will keep use_start_frm frames int sequential_counter = 0; while (sequential_counter < use_start_frm) { cap.read(img_origin); sequential_counter++; } int end_frm = use_start_frm + length * sampling_rate; CHECK_LE(end_frm, num_of_frames) << "end frame must be less or equal to num of frames"; for (int i=use_start_frm; i<end_frm; i++){ if (sampling_rate > 1) { // If sampling_rate > 1, purposely keep some frames if ((i-use_start_frm) % sampling_rate !=0) { cap.read(img_origin); continue; } } if (height > 0 && width > 0){ cap.read(img_origin); if (!img_origin.data){ LOG(INFO) << filename << " has no data at frame " << i; if (buffer!=NULL) delete[] buffer; return false; } cv::resize(img_origin, img, cv::Size(width, height)); } else cap.read(img); if (!img.data){ LOG(ERROR) << "Could not open or find file " << filename; if (buffer!=NULL) delete[] buffer; return false; } if (i==use_start_frm){ datum->set_height(img.rows); datum->set_width(img.cols); image_size = img.rows * img.cols; channel_size = image_size * length; data_size = channel_size * 3; buffer = new char[data_size]; } for (int c=0; c<3; c++){ ImageChannelToBuffer(&img, buffer + c * channel_size + offset, c); } offset += image_size; } CHECK(offset == channel_size) << "wrong offset size" << std::endl; datum->set_data(buffer, data_size); delete []buffer; cap.release(); return true; }
bool ReadVideoToVolumeDatum(const char* filename, const int start_frm, const int label, const int length, const int height, const int width, const int sampling_rate, VolumeDatum* datum) { cv::VideoCapture cap; cv::Mat img, img_origin; char *buffer; int offset, channel_size, image_size, data_size; int use_start_frm = start_frm; cap.open(filename); if (!cap.isOpened()) { LOG(ERROR) << "Cannot open " << filename; return false; } datum->set_channels(3); datum->set_length(length); datum->set_label(label); datum->clear_data(); datum->clear_float_data(); int num_of_frames = cap.get(CV_CAP_PROP_FRAME_COUNT); if (num_of_frames<length*sampling_rate) { LOG(INFO) << "not enough frames; having " << num_of_frames; return false; } if (start_frm < 0) { use_start_frm = rand()%(num_of_frames-length*sampling_rate+1); } offset = 0; CHECK_GE(use_start_frm, 0) << "start frame must be greater or equal to 0"; cap.set(CV_CAP_PROP_POS_FRAMES, use_start_frm); int end_frm = use_start_frm + length * sampling_rate; //CHECK_LE(end_frm, num_of_frames) << "end frame must less or equal to num of frames"; CHECK_LE(end_frm-1, num_of_frames) << "end frame-1 must less or equal to num of frames (filename=" << filename << ")"; for (int i=use_start_frm; i<end_frm; i+=sampling_rate) { if (sampling_rate > 1) cap.set(CV_CAP_PROP_POS_FRAMES, i); if (height > 0 && width > 0) { cap.read(img_origin); if (!img_origin.data) { LOG(INFO) << "No data at frame " << i << " in "<< filename; return false; } cv::resize(img_origin, img, cv::Size(width, height)); } else cap.read(img); if (!img.data) { LOG(ERROR) << "Could not open or find file " << filename; return false; } if (i==use_start_frm) { datum->set_height(img.rows); datum->set_width(img.cols); image_size = img.rows * img.cols; channel_size = image_size * length; data_size = channel_size * 3; buffer = new char[data_size]; } for (int c=0; c<3; c++) { ImageChannelToBuffer(&img, buffer + c * channel_size + offset, c); } offset += image_size; } CHECK(offset == channel_size) << "wrong offset size" << std::endl; datum->set_data(buffer, data_size); delete []buffer; cap.release(); return true; }