From 391596a1b211c5c061c6318e1f734837610c1f34 Mon Sep 17 00:00:00 2001 From: Wangyida Date: Wed, 15 Jul 2015 23:53:30 +0800 Subject: [PATCH] add feature extraction --- modules/cnn_3dobj/README.md | 6 +- .../cnn_3dobj/include/opencv2/cnn_3dobj.hpp | 21 +- .../cnn_3dobj/samples/build/binary_label_test | Bin 56 -> 0 bytes .../samples/build/binary_label_train | Bin 56 -> 0 bytes .../samples/build/train_linemod_triplet.sh | 13 +- .../cnn_3dobj/samples/feature_extraction.cpp | 202 ++++++++++++++++++ modules/cnn_3dobj/samples/image2db.cpp | 191 +++++++++++++++++ .../samples/sphereview_3dobj_demo.cpp | 135 +----------- modules/cnn_3dobj/src/cnn_3dobj.cpp | 142 +++++++++++- modules/cnn_3dobj/src/precomp.hpp | 3 + 10 files changed, 564 insertions(+), 149 deletions(-) delete mode 100644 modules/cnn_3dobj/samples/build/binary_label_test delete mode 100644 modules/cnn_3dobj/samples/build/binary_label_train create mode 100644 modules/cnn_3dobj/samples/feature_extraction.cpp create mode 100644 modules/cnn_3dobj/samples/image2db.cpp diff --git a/modules/cnn_3dobj/README.md b/modules/cnn_3dobj/README.md index 6a573edf8..a2e825116 100644 --- a/modules/cnn_3dobj/README.md +++ b/modules/cnn_3dobj/README.md @@ -12,8 +12,10 @@ $ mkdir build $ cd build $ cmake .. $ make -$ ./sphereview_test -radius=250 -ite_depth=1 -plymodel=../ape.ply -imagedir=../data/images_ape/ +$ ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ape.ply -imagedir=../data/images_ape/ -labeldir=../data/label_ape.txt -num_class=4 -label_class=0 +$ ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ant.ply -imagedir=../data/images_ant/ -labeldir=../data/label_ant.txt -num_class=4 -label_class=1 +$ ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/cow.ply -imagedir=../data/images_cow/ -labeldir=../data/label_cow.txt -num_class=4 -label_class=2 +$ ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/plane.ply -imagedir=../data/images_plane/ -labeldir=../data/label_plane.txt -num_class=4 -label_class=3 ============================================== -demo :$ ./sphereview_test -radius=250 -ite_depth=1 -plymodel=../ape.ply -imagedir=../data/images_ape/ Then press 'q' to run the demo for images generation when you see the gray background and a coordinate. ============================================== diff --git a/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp b/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp index 8b6dc1124..72e6f92db 100644 --- a/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp +++ b/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp @@ -49,10 +49,12 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include #include #include +#include #include - +using std::string; /** @defgroup cnn_3dobj CNN based on Caffe aimming at 3D object recognition and pose estimation */ namespace cv @@ -92,6 +94,23 @@ class CV_EXPORTS_W IcoSphere /** @brief Generating new view points from all triangles. */ CV_WRAP void subdivide(float v1[], float v2[], float v3[], int depth); + /** @brief Make all view points having the some distance from the focal point used by the camera view. + */ + CV_WRAP static uint32_t swap_endian(uint32_t val); + /** @brief Suit the position of bytes in 4 byte data structure for particular system. + */ + CV_WRAP cv::Point3d getCenter(cv::Mat cloud); + /** @brief Get the center of points on surface in .ply model. + */ + CV_WRAP float getRadius(cv::Mat cloud, cv::Point3d center); + /** @brief Get the proper camera radius from the view point to the center of model. + */ + CV_WRAP static void createHeader(int num_item, int rows, int cols, const char* headerPath); + /** @brief Create header in binary files collecting the image data and label. + */ + CV_WRAP static void writeBinaryfile(string filenameImg, const char* binaryPath, const char* headerPath, int num_item, int label_class); + /** @brief Write binary files used for training in other open source project. + */ }; //! @} diff --git a/modules/cnn_3dobj/samples/build/binary_label_test b/modules/cnn_3dobj/samples/build/binary_label_test deleted file mode 100644 index 6b81c383d2317670f26968351bf85a9e63fe870c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 VcmZQz;9z86U@!n;tbh>*000bm08#(| diff --git a/modules/cnn_3dobj/samples/build/binary_label_train b/modules/cnn_3dobj/samples/build/binary_label_train deleted file mode 100644 index 6b81c383d2317670f26968351bf85a9e63fe870c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 VcmZQz;9z86U@!n;tbh>*000bm08#(| diff --git a/modules/cnn_3dobj/samples/build/train_linemod_triplet.sh b/modules/cnn_3dobj/samples/build/train_linemod_triplet.sh index 31c7ab9b8..34b221041 100755 --- a/modules/cnn_3dobj/samples/build/train_linemod_triplet.sh +++ b/modules/cnn_3dobj/samples/build/train_linemod_triplet.sh @@ -8,18 +8,15 @@ cd build cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. make -j4 make test -make install +sudo make install cd .. cmake .. make -j4 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ape.ply -imagedir=../data/images_ape/ -labeldir=../data/label_ape.txt -num_class=2 -label_class=0 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ant.ply -imagedir=../data/images_ant/ -labeldir=../data/label_ant.txt -num_class=2 -label_class=1 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/apple.ply -imagedir=../data/images_apple/ -labeldir=../data/label_apple.txt -num_class=2 -label_class=2 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/lamp.ply -imagedir=../data/images_lamp/ -labeldir=../data/label_lamp.txt -num_class=2 -label_class=3 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/cow.ply -imagedir=../data/images_cow/ -labeldir=../data/label_cow.txt -num_class=2 -label_class=4 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/plane.ply -imagedir=../data/images_plane/ -labeldir=../data/label_plane.txt -num_class=2 -label_class=5 -./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/porsche.ply -imagedir=../data/images_porsche/ -labeldir=../data/label_porsche.txt -num_class=2 -label_class=6 +./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ape.ply -imagedir=../data/images_ape/ -labeldir=../data/label_ape.txt -num_class=4 -label_class=0 +./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ant.ply -imagedir=../data/images_ant/ -labeldir=../data/label_ant.txt -num_class=4 -label_class=1 +./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/cow.ply -imagedir=../data/images_cow/ -labeldir=../data/label_cow.txt -num_class=4 -label_class=2 +./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/plane.ply -imagedir=../data/images_plane/ -labeldir=../data/label_plane.txt -num_class=4 -label_class=3 echo "Creating leveldb..." diff --git a/modules/cnn_3dobj/samples/feature_extraction.cpp b/modules/cnn_3dobj/samples/feature_extraction.cpp new file mode 100644 index 000000000..e23076ca6 --- /dev/null +++ b/modules/cnn_3dobj/samples/feature_extraction.cpp @@ -0,0 +1,202 @@ +#include // for snprintf +#include +#include + +#include "boost/algorithm/string.hpp" +#include "google/protobuf/text_format.h" +#define CPU_ONLY +#include "caffe/blob.hpp" +#include "caffe/common.hpp" +#include "caffe/net.hpp" +#include "caffe/proto/caffe.pb.h" +#include "caffe/util/db.hpp" +#include "caffe/util/io.hpp" +#include "caffe/vision_layers.hpp" + +using caffe::Blob; +using caffe::Caffe; +using caffe::Datum; +using caffe::Net; +using boost::shared_ptr; +using std::string; +namespace db = caffe::db; + +template +int feature_extraction_pipeline(int argc, char** argv); +int main(int argc, char** argv) { + return feature_extraction_pipeline(argc, argv); +// return feature_extraction_pipeline(argc, argv); +} + +template +int feature_extraction_pipeline(int argc, char** argv) { + ::google::InitGoogleLogging(argv[0]); + const int num_required_args = 7; + /*if (argc < num_required_args) { + LOG(ERROR)<< + "This program takes in a trained network and an input data layer, and then" + " extract features of the input data produced by the net.\n" + "Usage: extract_features pretrained_net_param" + " feature_extraction_proto_file extract_feature_blob_name1[,name2,...]" + " save_feature_dataset_name1[,name2,...] num_mini_batches db_type" + " [CPU/GPU] [DEVICE_ID=0]\n" + "Note: you can extract multiple features in one pass by specifying" + " multiple feature blob names and dataset names seperated by ','." + " The names cannot contain white space characters and the number of blobs" + " and datasets must be equal."; + return 1; + }*/ + int arg_pos = num_required_args; + + arg_pos = num_required_args; + //if (argc > arg_pos && strcmp(argv[arg_pos], "GPU") == 0) { + if (argc > arg_pos && strcmp("CPU", "GPU") == 0) { + LOG(ERROR)<< "Using GPU"; + int device_id = 0; + if (argc > arg_pos + 1) { + device_id = atoi(argv[arg_pos + 1]); + CHECK_GE(device_id, 0); + } + LOG(ERROR) << "Using Device_id=" << device_id; + Caffe::SetDevice(device_id); + Caffe::set_mode(Caffe::GPU); + } else { + LOG(ERROR) << "Using CPU"; + Caffe::set_mode(Caffe::CPU); + } + + arg_pos = 0; // the name of the executable + //std::string pretrained_binary_proto(argv[++arg_pos]); + std::string pretrained_binary_proto("/home/wangyida/Desktop/caffe/examples/triplet/3d_triplet_iter_200.caffemodel"); + + // Expected prototxt contains at least one data layer such as + // the layer data_layer_name and one feature blob such as the + // fc7 top blob to extract features. + /* + layers { + name: "data_layer_name" + type: DATA + data_param { + source: "/path/to/your/images/to/extract/feature/images_leveldb" + mean_file: "/path/to/your/image_mean.binaryproto" + batch_size: 128 + crop_size: 227 + mirror: false + } + top: "data_blob_name" + top: "label_blob_name" + } + layers { + name: "drop7" + type: DROPOUT + dropout_param { + dropout_ratio: 0.5 + } + bottom: "fc7" + top: "fc7" + } + */ + //std::string feature_extraction_proto(argv[++arg_pos]); + std::string feature_extraction_proto("/home/wangyida/Desktop/caffe/examples/triplet/3d_triplet.prototxt"); + boost::shared_ptr > feature_extraction_net( + new Net(feature_extraction_proto, caffe::TEST)); + feature_extraction_net->CopyTrainedLayersFrom(pretrained_binary_proto); + + //std::string extract_feature_blob_names(argv[++arg_pos]); + std::string extract_feature_blob_names("feat"); + std::vector blob_names; + boost::split(blob_names, extract_feature_blob_names, boost::is_any_of(",")); + + //std::string save_feature_dataset_names(argv[++arg_pos]); + std::string save_feature_dataset_names("/home/wangyida/Desktop/caffe/examples/triplet/feature_extracted"); + std::vector dataset_names; + boost::split(dataset_names, save_feature_dataset_names, + boost::is_any_of(",")); + CHECK_EQ(blob_names.size(), dataset_names.size()) << + " the number of blob names and dataset names must be equal"; + size_t num_features = blob_names.size(); + + for (size_t i = 0; i < num_features; i++) { + CHECK(feature_extraction_net->has_blob(blob_names[i])) + << "Unknown feature blob name " << blob_names[i] + << " in the network " << feature_extraction_proto; + } + + //int num_mini_batches = atoi(argv[++arg_pos]); + int num_mini_batches = atoi("6"); + + /*std::vector > feature_dbs; + std::vector > txns; + const char* db_type = argv[++arg_pos]; + for (size_t i = 0; i < num_features; ++i) { + LOG(INFO)<< "Opening dataset " << dataset_names[i]; + shared_ptr db(db::GetDB(db_type)); + db->Open(dataset_names.at(i), db::NEW); + feature_dbs.push_back(db); + shared_ptr txn(db->NewTransaction()); + txns.push_back(txn); + }*/ + std::vector files; + for (size_t i = 0; i < num_features; ++i) + { + LOG(INFO) << "Opening file " << dataset_names[i]; + FILE * temp = NULL; + temp = fopen(dataset_names[i].c_str(), "wb"); + files.push_back(temp); + } + + + LOG(ERROR)<< "Extacting Features"; + + //bool header_flag = true; + + Datum datum; + //const int kMaxKeyStrLength = 100; + //char key_str[kMaxKeyStrLength]; + std::vector*> input_vec; + std::vector image_indices(num_features, 0); + for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index) { + feature_extraction_net->Forward(input_vec); + for (int i = 0; i < num_features; ++i) { + const boost::shared_ptr > feature_blob = feature_extraction_net + ->blob_by_name(blob_names[i]); + int batch_size = feature_blob->num(); + int dim_features = feature_blob->count() / batch_size; + if (batch_index == 0) + { + int fea_num = batch_size*num_mini_batches; + fwrite(&dim_features, sizeof(int), 1, files[i]); + fwrite(&fea_num, sizeof(int), 1, files[i]); + //bool header_flag = false; + } + const Dtype* feature_blob_data; + for (int n = 0; n < batch_size; ++n) { + + feature_blob_data = feature_blob->cpu_data() + + feature_blob->offset(n); + fwrite(feature_blob_data, sizeof(Dtype), dim_features, files[i]); + + ++image_indices[i]; + if (image_indices[i] % 1000 == 0) { + LOG(ERROR)<< "Extracted features of " << image_indices[i] << + " query images for feature blob " << blob_names[i]; + } + } // for (int n = 0; n < batch_size; ++n) + } // for (int i = 0; i < num_features; ++i) + } // for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index) + // write the last batch + for (int i = 0; i < num_features; ++i) { + /* if (image_indices[i] % 1000 != 0) { + txns.at(i)->Commit(); + } + LOG(ERROR)<< "Extracted features of " << image_indices[i] << + " query images for feature blob " << blob_names[i]; + feature_dbs.at(i)->Close();*/ + fclose(files[i]); + } + + LOG(ERROR)<< "Successfully extracted the features!"; + return 0; +} + + diff --git a/modules/cnn_3dobj/samples/image2db.cpp b/modules/cnn_3dobj/samples/image2db.cpp new file mode 100644 index 000000000..03bcb7a96 --- /dev/null +++ b/modules/cnn_3dobj/samples/image2db.cpp @@ -0,0 +1,191 @@ +#include +#include +#include + +#include +#include // NOLINT(readability/streams) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caffe/proto/caffe.pb.h" +#include +#include +#include + +using std::string; +using namespace std; + + +set all_class_name; +map class2id; + +void list_dir(const char *path,vector& files,bool r = false) +{ + DIR *pDir; + struct dirent *ent; + char childpath[512]; + pDir = opendir(path); + memset(childpath, 0, sizeof(childpath)); + while ((ent = readdir(pDir)) != NULL) + { + if (ent->d_type & DT_DIR) + { + + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) + { + continue; + } + if(r) + { + sprintf(childpath, "%s/%s", path, ent->d_name); + list_dir(childpath,files); + } + } + else + { + files.push_back(ent->d_name); + } + } + sort(files.begin(),files.end()); + +} + +string get_classname(string path) +{ + int index = path.find_last_of('_'); + return path.substr(0, index); +} + + +int get_labelid(string fileName) +{ + string class_name_tmp = get_classname(fileName); + all_class_name.insert(class_name_tmp); + map::iterator name_iter_tmp = class2id.find(class_name_tmp); + if (name_iter_tmp == class2id.end()) + { + int id = class2id.size(); + class2id.insert(name_iter_tmp, std::make_pair(class_name_tmp, id)); + return id; + } + else + { + return name_iter_tmp->second; + } +} + +void loadimg(string path,char* buffer) +{ + cv::Mat img = cv::imread(path, CV_LOAD_IMAGE_COLOR); + string val; + int rows = img.rows; + int cols = img.cols; + int pos=0; + for (int c = 0; c < 3; c++) + { + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { + buffer[pos++]=img.at(row,col)[c]; + } + } + } + +} +void convert(string imgdir,string outputdb,string attachdir,int channel,int width,int height) +{ + leveldb::DB* db; + leveldb::Options options; + options.create_if_missing = true; + options.error_if_exists = true; + caffe::Datum datum; + datum.set_channels(channel); + datum.set_height(height); + datum.set_width(width); + int image_size = channel*width*height; + char buffer[image_size]; + + string value; + CHECK(leveldb::DB::Open(options, outputdb, &db).ok()); + vector filenames; + list_dir(imgdir.c_str(),filenames); + string img_log = attachdir+"image_filename"; + ofstream writefile(img_log.c_str()); + for(int i=0;iPut(leveldb::WriteOptions(),string(buffer),value); + //printf("%d %s\n",i,fileNames[i].c_str()); + + assert(writefile.is_open()); + writefile<::iterator iter = all_class_name.begin(); + while(iter != all_class_name.end()) + { + assert(writefile.is_open()); + writefile<<(*iter)<<"\n"; + //printf("%s\n",(*iter).c_str()); + iter++; + } + writefile.close(); + +} + +int main(int argc, char** argv) +{ + if (argc < 6) + { + LOG(ERROR) << "convert_imagedata src_dir dst_dir attach_dir channel width height"; + return 0; + } +//./convert_imagedata.bin /home/linger/imdata/collarTest/ /home/linger/linger/testfile/dbtest/ /home/linger/linger/testfile/test_attachment/ 3 250 250 + // ./convert_imagedata.bin /home/linger/imdata/collar_train/ /home/linger/linger/testfile/crop_train_db/ /home/linger/linger/testfile/crop_train_attachment/ 3 50 50 + google::InitGoogleLogging(argv[0]); + string src_dir = argv[1]; + string src_dst = argv[2]; + string attach_dir = argv[3]; + int channel = atoi(argv[4]); + int width = atoi(argv[5]); + int height = atoi(argv[6]); + + //for test + /* + src_dir = "/home/linger/imdata/collarTest/"; + src_dst = "/home/linger/linger/testfile/dbtest/"; + attach_dir = "/home/linger/linger/testfile/"; + channel = 3; + width = 250; + height = 250; + */ + + convert(src_dir,src_dst,attach_dir,channel,width,height); + + + +} + diff --git a/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp b/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp index 7f91a5637..b9adf09e2 100644 --- a/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp +++ b/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp @@ -35,135 +35,12 @@ #include #include #include -#include -#include #include -#include using namespace cv; using namespace std; using namespace cv::cnn_3dobj; -uint32_t swap_endian(uint32_t val) { - val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF); - return (val << 16) | (val >> 16); -} -Point3d getCenter(cv::Mat cloud) -{ - Point3f* data = cloud.ptr(); - Point3d dataout; - for(int i = 0; i < cloud.cols; ++i) - { - dataout.x += data[i].x; - dataout.y += data[i].y; - dataout.z += data[i].z; - } - dataout.x = dataout.x/cloud.cols; - dataout.y = dataout.y/cloud.cols; - dataout.z = dataout.z/cloud.cols; - return dataout; -}; -float getRadius(cv::Mat cloud, Point3d center) -{ - float radius = 0; - Point3f* data = cloud.ptr(); - Point3d datatemp; - for(int i = 0; i < cloud.cols; ++i) - { - datatemp.x = data[i].x - (float)center.x; - datatemp.y = data[i].y - (float)center.y; - datatemp.z = data[i].z - (float)center.z; - float Radius = sqrt(pow(datatemp.x,2)+pow(datatemp.y,2)+pow(datatemp.z,2)); - if(Radius > radius) - { - radius = Radius; - } - } - radius = radius*3; - return radius; -}; -void createHeader(int num_item, int rows, int cols, const char* headerPath) -{ - char* a0 = new char; - strcpy(a0, headerPath); - char a1[] = "image"; - char a2[] = "label"; - char* headerPathimg = new char; - strcpy(headerPathimg, a0); - strcat(headerPathimg, a1); - char* headerPathlab = new char; - strcpy(headerPathlab, a0); - strcat(headerPathlab, a2); - std::ofstream headerImg(headerPathimg, ios::out|ios::binary); - std::ofstream headerLabel(headerPathlab, ios::out|ios::binary); - int headerimg[4] = {2051,num_item,rows,cols}; - for (int i=0; i<4; i++) - headerimg[i] = swap_endian(headerimg[i]); - int headerlabel[2] = {2049,num_item}; - for (int i=0; i<2; i++) - headerlabel[i] = swap_endian(headerlabel[i]); - headerImg.write(reinterpret_cast(headerimg), sizeof(int)*4); - headerImg.close(); - headerLabel.write(reinterpret_cast(headerlabel), sizeof(int)*2); - headerLabel.close(); -}; -void writeBinaryfile(string filename, const char* binaryPath, const char* headerPath, int num_item, int label_class) -{ - int isrgb = 0; - cv::Mat ImgforBin = cv::imread(filename, isrgb); - char* A0 = new char; - strcpy(A0, binaryPath); - char A1[] = "image"; - char A2[] = "label"; - char* binPathimg = new char; - strcpy(binPathimg, A0); - strcat(binPathimg, A1); - char* binPathlab = new char; - strcpy(binPathlab, A0); - strcat(binPathlab, A2); - fstream img_file, lab_file; - img_file.open(binPathimg,ios::in); - lab_file.open(binPathlab,ios::in); - if(!img_file) - { - cout << "Creating the training data at: " << binaryPath << ". " << endl; - char* a0 = new char; - strcpy(a0, headerPath); - char a1[] = "image"; - char a2[] = "label"; - char* headerPathimg = new char; - strcpy(headerPathimg, a0); - strcat(headerPathimg,a1); - char* headerPathlab = new char; - strcpy(headerPathlab, a0); - strcat(headerPathlab,a2); - createHeader(num_item, 250, 250, binaryPath); - ofstream img_file(binPathimg,ios::out|ios::binary|ios::app); - ofstream lab_file(binPathlab,ios::out|ios::binary|ios::app); - for (int r = 0; r < ImgforBin.rows; r++) - { - img_file.write(reinterpret_cast(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize()); - } - unsigned char templab = (unsigned char)label_class; - lab_file << templab; - } - else - { - img_file.close(); - lab_file.close(); - img_file.open(binPathimg,ios::out|ios::binary|ios::app); - lab_file.open(binPathlab,ios::out|ios::binary|ios::app); - cout <<"Concatenating the training data at: " << binaryPath << ". " << endl; - for (int r = 0; r < ImgforBin.rows; r++) - { - img_file.write(reinterpret_cast(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize()); - } - unsigned char templab = (unsigned char)label_class; - lab_file << templab; - } - img_file.close(); - lab_file.close(); -}; int main(int argc, char *argv[]){ - const String keys = "{help | | demo :$ ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ape.ply -imagedir=../data/images_ape/ -labeldir=../data/label_ape.txt -num_class=2 -label_class=0, then press 'q' to run the demo for images generation when you see the gray background and a coordinate.}" + const String keys = "{help | | demo :$ ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/ape.ply -imagedir=../data/images_ape/ -labeldir=../data/label_ape.txt -num_class=4 -label_class=0, then press 'q' to run the demo for images generation when you see the gray background and a coordinate.}" "{ite_depth | 1 | Iteration of sphere generation.}" "{plymodel | ../ape.ply | path of the '.ply' file for image rendering. }" "{imagedir | ../data/images_ape/ | path of the generated images for one particular .ply model. }" @@ -191,7 +68,7 @@ int main(int argc, char *argv[]){ bool camera_pov = (true); /// Create a window viz::Viz3d myWindow("Coordinate Frame"); - myWindow.setWindowSize(Size(250,250)); + myWindow.setWindowSize(Size(64,64)); /// Add coordinate axes myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); myWindow.setBackgroundColor(viz::Color::gray()); @@ -200,12 +77,12 @@ int main(int argc, char *argv[]){ /// Let's assume camera has the following properties /// Create a cloud widget. viz::Mesh objmesh = viz::Mesh::load(plymodel); - Point3d cam_focal_point = getCenter(objmesh.cloud); - float radius = getRadius(objmesh.cloud, cam_focal_point); + Point3d cam_focal_point = ViewSphere.getCenter(objmesh.cloud); + float radius = ViewSphere.getRadius(objmesh.cloud, cam_focal_point); Point3d cam_y_dir(0.0f,0.0f,1.0f); const char* headerPath = "./header_for_"; const char* binaryPath = "./binary_"; - createHeader((int)campos.size(), 250, 250, headerPath); + ViewSphere.createHeader((int)campos.size(), 64, 64, headerPath); for(int pose = 0; pose < (int)campos.size(); pose++){ imglabel << campos.at(pose).x << ' ' << campos.at(pose).y << ' ' << campos.at(pose).z << endl; /// We can get the pose of the cam using makeCameraPoses @@ -240,7 +117,7 @@ int main(int argc, char *argv[]){ filename = imagedir + filename; filename += ".png"; myWindow.saveScreenshot(filename); - writeBinaryfile(filename, binaryPath, headerPath,(int)campos.size()*num_class, label_class); + ViewSphere.writeBinaryfile(filename, binaryPath, headerPath,(int)campos.size()*num_class, label_class); } return 1; }; diff --git a/modules/cnn_3dobj/src/cnn_3dobj.cpp b/modules/cnn_3dobj/src/cnn_3dobj.cpp index 40c350df2..7a8681245 100644 --- a/modules/cnn_3dobj/src/cnn_3dobj.cpp +++ b/modules/cnn_3dobj/src/cnn_3dobj.cpp @@ -2,17 +2,18 @@ using namespace cv; using namespace std; -namespace cv{ namespace cnn_3dobj{ +namespace cv +{ +namespace cnn_3dobj +{ IcoSphere::IcoSphere(float radius_in, int depth_in) { X = 0.5f; Z = 0.5f; - int radius = radius_in; - int depth = depth_in; - X *= radius; - Z *= radius; + X *= (int)radius_in; + Z *= (int)radius_in; diff = 0.00000005964; float vdata[12][3] = { { -X, 0.0f, Z }, { X, 0.0f, Z }, { -X, 0.0f, -Z }, { X, 0.0f, -Z }, { 0.0f, Z, X }, { 0.0f, Z, -X }, @@ -26,14 +27,11 @@ namespace cv{ namespace cnn_3dobj{ { 11, 0, 6 }, { 0, 1, 6 }, { 6, 1, 10 }, { 9, 0, 11 }, { 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 } }; - std::vector* texCoordsList = new std::vector; - std::vector* indicesList = new std::vector; - // Iterate over points for (int i = 0; i < 20; ++i) { subdivide(vdata[tindices[i][0]], vdata[tindices[i][1]], - vdata[tindices[i][2]], depth); + vdata[tindices[i][2]], depth_in); } CameraPos_temp.push_back(CameraPos[0]); for (int j = 1; j> 8) & 0xFF00FF); + return (val << 16) | (val >> 16); + } + + cv::Point3d IcoSphere::getCenter(cv::Mat cloud) + { + Point3f* data = cloud.ptr(); + Point3d dataout; + for(int i = 0; i < cloud.cols; ++i) + { + dataout.x += data[i].x; + dataout.y += data[i].y; + dataout.z += data[i].z; + } + dataout.x = dataout.x/cloud.cols; + dataout.y = dataout.y/cloud.cols; + dataout.z = dataout.z/cloud.cols; + return dataout; + } + + float IcoSphere::getRadius(cv::Mat cloud, cv::Point3d center) + { + float radiusCam = 0; + Point3f* data = cloud.ptr(); + Point3d datatemp; + for(int i = 0; i < cloud.cols; ++i) + { + datatemp.x = data[i].x - (float)center.x; + datatemp.y = data[i].y - (float)center.y; + datatemp.z = data[i].z - (float)center.z; + float Radius = sqrt(pow(datatemp.x,2)+pow(datatemp.y,2)+pow(datatemp.z,2)); + if(Radius > radiusCam) + { + radiusCam = Radius; + } + } + radiusCam *= 4; + return radiusCam; + }; + + void IcoSphere::createHeader(int num_item, int rows, int cols, const char* headerPath) + { + char* a0 = (char*)malloc(1024); + strcpy(a0, headerPath); + char a1[] = "image"; + char a2[] = "label"; + char* headerPathimg = (char*)malloc(1024); + strcpy(headerPathimg, a0); + strcat(headerPathimg, a1); + char* headerPathlab = (char*)malloc(1024); + strcpy(headerPathlab, a0); + strcat(headerPathlab, a2); + std::ofstream headerImg(headerPathimg, ios::out|ios::binary); + std::ofstream headerLabel(headerPathlab, ios::out|ios::binary); + int headerimg[4] = {2051,num_item,rows,cols}; + for (int i=0; i<4; i++) + headerimg[i] = swap_endian(headerimg[i]); + int headerlabel[2] = {2049,num_item}; + for (int i=0; i<2; i++) + headerlabel[i] = swap_endian(headerlabel[i]); + headerImg.write(reinterpret_cast(headerimg), sizeof(int)*4); + headerImg.close(); + headerLabel.write(reinterpret_cast(headerlabel), sizeof(int)*2); + headerLabel.close(); + }; + + void IcoSphere::writeBinaryfile(string filenameImg, const char* binaryPath, const char* headerPath, int num_item, int label_class) + { + int isrgb = 0; + cv::Mat ImgforBin = cv::imread(filenameImg, isrgb); + char* A0 = (char*)malloc(1024); + strcpy(A0, binaryPath); + char A1[] = "image"; + char A2[] = "label"; + char* binPathimg = (char*)malloc(1024); + strcpy(binPathimg, A0); + strcat(binPathimg, A1); + char* binPathlab = (char*)malloc(1024); + strcpy(binPathlab, A0); + strcat(binPathlab, A2); + fstream img_file, lab_file; + img_file.open(binPathimg,ios::in); + lab_file.open(binPathlab,ios::in); + if(!img_file) + { + cout << "Creating the training data at: " << binaryPath << ". " << endl; + char* a0 = (char*)malloc(1024); + strcpy(a0, headerPath); + char a1[] = "image"; + char a2[] = "label"; + char* headerPathimg = (char*)malloc(1024); + strcpy(headerPathimg, a0); + strcat(headerPathimg,a1); + char* headerPathlab = (char*)malloc(1024); + strcpy(headerPathlab, a0); + strcat(headerPathlab,a2); + createHeader(num_item, 64, 64, binaryPath); + img_file.open(binPathimg,ios::out|ios::binary|ios::app); + lab_file.open(binPathlab,ios::out|ios::binary|ios::app); + for (int r = 0; r < ImgforBin.rows; r++) + { + img_file.write(reinterpret_cast(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize()); + } + unsigned char templab = (unsigned char)label_class; + lab_file << templab; + } + else + { + img_file.close(); + lab_file.close(); + img_file.open(binPathimg,ios::out|ios::binary|ios::app); + lab_file.open(binPathlab,ios::out|ios::binary|ios::app); + cout <<"Concatenating the training data at: " << binaryPath << ". " << endl; + for (int r = 0; r < ImgforBin.rows; r++) + { + img_file.write(reinterpret_cast(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize()); + } + unsigned char templab = (unsigned char)label_class; + lab_file << templab; + } + img_file.close(); + lab_file.close(); + }; }} diff --git a/modules/cnn_3dobj/src/precomp.hpp b/modules/cnn_3dobj/src/precomp.hpp index 0e5933790..60a3ce2f4 100644 --- a/modules/cnn_3dobj/src/precomp.hpp +++ b/modules/cnn_3dobj/src/precomp.hpp @@ -48,6 +48,9 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include +#include #include +#include #endif