add feature extraction

pull/276/head
Wangyida 9 years ago
parent 9fdc78a302
commit 391596a1b2
  1. 6
      modules/cnn_3dobj/README.md
  2. 21
      modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp
  3. BIN
      modules/cnn_3dobj/samples/build/binary_label_test
  4. BIN
      modules/cnn_3dobj/samples/build/binary_label_train
  5. 13
      modules/cnn_3dobj/samples/build/train_linemod_triplet.sh
  6. 202
      modules/cnn_3dobj/samples/feature_extraction.cpp
  7. 191
      modules/cnn_3dobj/samples/image2db.cpp
  8. 135
      modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp
  9. 142
      modules/cnn_3dobj/src/cnn_3dobj.cpp
  10. 3
      modules/cnn_3dobj/src/precomp.hpp

@ -12,8 +12,10 @@ $ mkdir build
$ cd build $ cd build
$ cmake .. $ cmake ..
$ make $ 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. Then press 'q' to run the demo for images generation when you see the gray background and a coordinate.
============================================== ==============================================

@ -49,10 +49,12 @@ the use of this software, even if advised of the possibility of such damage.
#include <opencv2/calib3d.hpp> #include <opencv2/calib3d.hpp>
#include <opencv2/viz/vizcore.hpp> #include <opencv2/viz/vizcore.hpp>
#include <opencv2/highgui.hpp> #include <opencv2/highgui.hpp>
#include <string>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <stdio.h>
#include <iostream> #include <iostream>
using std::string;
/** @defgroup cnn_3dobj CNN based on Caffe aimming at 3D object recognition and pose estimation /** @defgroup cnn_3dobj CNN based on Caffe aimming at 3D object recognition and pose estimation
*/ */
namespace cv namespace cv
@ -92,6 +94,23 @@ class CV_EXPORTS_W IcoSphere
/** @brief Generating new view points from all triangles. /** @brief Generating new view points from all triangles.
*/ */
CV_WRAP void subdivide(float v1[], float v2[], float v3[], int depth); 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.
*/
}; };
//! @} //! @}

@ -8,18 +8,15 @@ cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
make -j4 make -j4
make test make test
make install sudo make install
cd .. cd ..
cmake .. cmake ..
make -j4 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/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=2 -label_class=1 ./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/apple.ply -imagedir=../data/images_apple/ -labeldir=../data/label_apple.txt -num_class=2 -label_class=2 ./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/lamp.ply -imagedir=../data/images_lamp/ -labeldir=../data/label_lamp.txt -num_class=2 -label_class=3 ./sphereview_test -ite_depth=2 -plymodel=../3Dmodel/plane.ply -imagedir=../data/images_plane/ -labeldir=../data/label_plane.txt -num_class=4 -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
echo "Creating leveldb..." echo "Creating leveldb..."

@ -0,0 +1,202 @@
#include <stdio.h> // for snprintf
#include <string>
#include <vector>
#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<typename Dtype>
int feature_extraction_pipeline(int argc, char** argv);
int main(int argc, char** argv) {
return feature_extraction_pipeline<float>(argc, argv);
// return feature_extraction_pipeline<double>(argc, argv);
}
template<typename Dtype>
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<Net<Dtype> > feature_extraction_net(
new Net<Dtype>(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<std::string> 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<std::string> 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<shared_ptr<db::DB> > feature_dbs;
std::vector<shared_ptr<db::Transaction> > 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> db(db::GetDB(db_type));
db->Open(dataset_names.at(i), db::NEW);
feature_dbs.push_back(db);
shared_ptr<db::Transaction> txn(db->NewTransaction());
txns.push_back(txn);
}*/
std::vector<FILE*> 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<Blob<float>*> input_vec;
std::vector<int> 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<Blob<Dtype> > 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;
}

@ -0,0 +1,191 @@
#include <google/protobuf/text_format.h>
#include <glog/logging.h>
#include <leveldb/db.h>
#include <stdint.h>
#include <fstream> // NOLINT(readability/streams)
#include <string>
#include <set>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include "caffe/proto/caffe.pb.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgproc/imgproc.hpp>
using std::string;
using namespace std;
set<string> all_class_name;
map<string,int> class2id;
void list_dir(const char *path,vector<string>& 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<string,int>::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<cv::Vec3b>(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<string> filenames;
list_dir(imgdir.c_str(),filenames);
string img_log = attachdir+"image_filename";
ofstream writefile(img_log.c_str());
for(int i=0;i<filenames.size();i++)
{
string path= imgdir;
path.append(filenames[i]);
loadimg(path,buffer);
int labelid = get_labelid(filenames[i]);
datum.set_label(labelid);
datum.set_data(buffer,image_size);
datum.SerializeToString(&value);
snprintf(buffer, image_size, "%05d", i);
printf("\nclassid:%d classname:%s abspath:%s",labelid,get_classname(filenames[i]).c_str(),path.c_str());
db->Put(leveldb::WriteOptions(),string(buffer),value);
//printf("%d %s\n",i,fileNames[i].c_str());
assert(writefile.is_open());
writefile<<i<<" "<<filenames[i]<<"\n";
}
delete db;
writefile.close();
img_log = attachdir+"image_classname";
writefile.open(img_log.c_str());
set<string>::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);
}

@ -35,135 +35,12 @@
#include <opencv2/cnn_3dobj.hpp> #include <opencv2/cnn_3dobj.hpp>
#include <opencv2/viz/vizcore.hpp> #include <opencv2/viz/vizcore.hpp>
#include <iostream> #include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
using namespace cv; using namespace cv;
using namespace std; using namespace std;
using namespace cv::cnn_3dobj; 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<cv::Point3f>();
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<cv::Point3f>();
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<const char*>(headerimg), sizeof(int)*4);
headerImg.close();
headerLabel.write(reinterpret_cast<const char*>(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<const char*>(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<const char*>(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[]){ 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.}" "{ite_depth | 1 | Iteration of sphere generation.}"
"{plymodel | ../ape.ply | path of the '.ply' file for image rendering. }" "{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. }" "{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); bool camera_pov = (true);
/// Create a window /// Create a window
viz::Viz3d myWindow("Coordinate Frame"); viz::Viz3d myWindow("Coordinate Frame");
myWindow.setWindowSize(Size(250,250)); myWindow.setWindowSize(Size(64,64));
/// Add coordinate axes /// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
myWindow.setBackgroundColor(viz::Color::gray()); myWindow.setBackgroundColor(viz::Color::gray());
@ -200,12 +77,12 @@ int main(int argc, char *argv[]){
/// Let's assume camera has the following properties /// Let's assume camera has the following properties
/// Create a cloud widget. /// Create a cloud widget.
viz::Mesh objmesh = viz::Mesh::load(plymodel); viz::Mesh objmesh = viz::Mesh::load(plymodel);
Point3d cam_focal_point = getCenter(objmesh.cloud); Point3d cam_focal_point = ViewSphere.getCenter(objmesh.cloud);
float radius = getRadius(objmesh.cloud, cam_focal_point); float radius = ViewSphere.getRadius(objmesh.cloud, cam_focal_point);
Point3d cam_y_dir(0.0f,0.0f,1.0f); Point3d cam_y_dir(0.0f,0.0f,1.0f);
const char* headerPath = "./header_for_"; const char* headerPath = "./header_for_";
const char* binaryPath = "./binary_"; 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++){ for(int pose = 0; pose < (int)campos.size(); pose++){
imglabel << campos.at(pose).x << ' ' << campos.at(pose).y << ' ' << campos.at(pose).z << endl; imglabel << campos.at(pose).x << ' ' << campos.at(pose).y << ' ' << campos.at(pose).z << endl;
/// We can get the pose of the cam using makeCameraPoses /// We can get the pose of the cam using makeCameraPoses
@ -240,7 +117,7 @@ int main(int argc, char *argv[]){
filename = imagedir + filename; filename = imagedir + filename;
filename += ".png"; filename += ".png";
myWindow.saveScreenshot(filename); 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; return 1;
}; };

@ -2,17 +2,18 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
namespace cv{ namespace cnn_3dobj{ namespace cv
{
namespace cnn_3dobj
{
IcoSphere::IcoSphere(float radius_in, int depth_in) IcoSphere::IcoSphere(float radius_in, int depth_in)
{ {
X = 0.5f; X = 0.5f;
Z = 0.5f; Z = 0.5f;
int radius = radius_in; X *= (int)radius_in;
int depth = depth_in; Z *= (int)radius_in;
X *= radius;
Z *= radius;
diff = 0.00000005964; diff = 0.00000005964;
float vdata[12][3] = { { -X, 0.0f, Z }, { X, 0.0f, Z }, 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 }, { -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 }, { 11, 0, 6 }, { 0, 1, 6 }, { 6, 1, 10 }, { 9, 0, 11 },
{ 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 } }; { 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 } };
std::vector<float>* texCoordsList = new std::vector<float>;
std::vector<int>* indicesList = new std::vector<int>;
// Iterate over points // Iterate over points
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
subdivide(vdata[tindices[i][0]], vdata[tindices[i][1]], 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]); CameraPos_temp.push_back(CameraPos[0]);
for (int j = 1; j<int(CameraPos.size()); j++) for (int j = 1; j<int(CameraPos.size()); j++)
@ -114,4 +112,130 @@ namespace cv{ namespace cnn_3dobj{
subdivide(v3, v31, v23, depth - 1); subdivide(v3, v31, v23, depth - 1);
subdivide(v12, v23, v31, depth - 1); subdivide(v12, v23, v31, depth - 1);
} }
uint32_t IcoSphere::swap_endian(uint32_t val)
{
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
return (val << 16) | (val >> 16);
}
cv::Point3d IcoSphere::getCenter(cv::Mat cloud)
{
Point3f* data = cloud.ptr<cv::Point3f>();
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<cv::Point3f>();
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<const char*>(headerimg), sizeof(int)*4);
headerImg.close();
headerLabel.write(reinterpret_cast<const char*>(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<const char*>(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<const char*>(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize());
}
unsigned char templab = (unsigned char)label_class;
lab_file << templab;
}
img_file.close();
lab_file.close();
};
}} }}

@ -48,6 +48,9 @@ the use of this software, even if advised of the possibility of such damage.
#include <opencv2/highgui.hpp> #include <opencv2/highgui.hpp>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <string>
#include <stdio.h>
#include <iostream> #include <iostream>
#include <math.h>
#endif #endif

Loading…
Cancel
Save