add error solving tips and information about model in README

pull/276/head
Wangyida 10 years ago
parent e4e374e217
commit 736638710e
  1. 59
      modules/cnn_3dobj/README.md
  2. 173
      modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp
  3. 5
      modules/cnn_3dobj/include/opencv2/cnn_3dobj_config.hpp
  4. 15
      modules/cnn_3dobj/samples/classifyIMG_demo.cpp
  5. 449
      modules/cnn_3dobj/src/cnn_feature.cpp
  6. 422
      modules/cnn_3dobj/src/cnn_sphereview.cpp

@ -1,17 +1,27 @@
##CNN for 3D object recognition and pose estimation including a completed Sphere View of 3D objects from .ply files, when the windows shows the coordinate, press 'q' to go on image generation.
#Convolutional Neural Network for 3D object classification and pose estimation.
============================================
#Building Process:
###Prerequisite for this module: protobuf, leveldb, glog, gflags and caffe, for the libcaffe installation, you can install it on standard system path for being able to be linked by this OpenCV module when compiling. Just using: -D CMAKE_INSTALL_PREFIX=/usr/local, so the building process on Caffe on system could be like this:
#Module Description on cnn_3dobj:
This learning structure construction and feature extraction concept is based on Convolutional Neural Network, the main reference paper could be found at:
https://cvarlab.icg.tugraz.at/pubs/wohlhart_cvpr15.pdf
The author provided Codes on Theano on:
https://cvarlab.icg.tugraz.at/projects/3d_object_detection/
I implemented the training and feature extraction codes mainly based on CAFFE project which will be compiled as libcaffe for the cnn_3dobj OpenCV module, codes are mainly concentrating on triplet and pair-wise jointed loss layer, the training data arrangement is also important which basic training information.
Codes about my triplet version of caffe are released on GIthub, you can git it through:
```
$ git clone https://github.com/Wangyida/caffe/tree/cnn_triplet.
```
============================================
#Module Building Process:
###Prerequisite for this module: protobuf and caffe, for the libcaffe installation, you can install it on standard system path for the aim of being able to be linked by this OpenCV module when compiling and function using. Using: -D CMAKE_INSTALL_PREFIX=/usr/local as an building option when you cmake, the building process on Caffe on system could be like this:
```
$ cd <caffe_source_directory>
$ mkdir biuld
$ cd build
$ cmake -D CMAKE_INSTALL_PREFIX=/usr/local ..
$ make all
$ make install
$ make all -j4
$ sudo make install
```
###After all these steps, the headers and libs of caffe will be set on /usr/local/ path, and when you compiling opencv with opencv_contrib modules as below, the protobif, leveldb, glog, gflags and caffe will be recognized as already installed while building.
###After all these steps, the headers and libs of CAFFE will be set on /usr/local/ path, and when you compiling opencv with opencv_contrib modules as below, the protobuf and caffe will be recognized as already installed while building. Protobuf is
#Compiling OpenCV
```
@ -22,7 +32,14 @@ $ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_T
$ make -j4
$ sudo make install
```
##Tips on compiling problems:
###If you encouter the no declaration errors when you 'make', it might becaused that you have installed the older version of cnn_3dobj module and the header file changed in a newly released version of codes. This problem is the cmake and make can't detect the header should be updated and it keeps the older header remains in /usr/local/include/opencv2 whithout updating. This error could be solved by remove the installed older version of cnn_3dobj module by:
```
$ cd /
$ cd usr/local/include/opencv2/
$ sudo rm -rf cnn_3dobj.hpp
```
###And redo the compiling steps above again.
================================================
#Building samples
```
@ -34,41 +51,43 @@ $ make
```
=============
#Demo1:
###Imagas generation from different pose, 4 models are used, there will be 276 images in all which each class contains 69 iamges
#Demos
##Demo1: training data generation
###Imagas generation from different pose, by default there are 4 models used, there will be 276 images in all which each class contains 69 iamges, if you want to use additional .ply models, it is necessary to change the class number parameter to the new class number and also give it a new class label.
```
$ ./sphereview_test -plymodel=../3Dmodel/ape.ply -label_class=0
```
###press q to start
###press 'Q' to start 2D image genaration
```
$ ./sphereview_test -plymodel=../3Dmodel/ant.ply -label_class=1
```
###press q to start
###press 'Q' to start
```
$ ./sphereview_test -plymodel=../3Dmodel/cow.ply -label_class=2
```
###press q to start
###press 'Q' to start
```
$ ./sphereview_test -plymodel=../3Dmodel/plane.ply -label_class=3
```
###press q to start, when all images are created in images_all folder as a collection of images for network tranining and feature extraction, then proceed on.
###After this demo, the binary files of images and labels will be stored as 'binary_image' and 'binary_label' in current path, you should copy them into the leveldb folder in Caffe triplet training, for example: copy these 2 files in <caffe_source_directory>/data/linemod and rename them as 'binary_image_train', 'binary_image_test' and 'binary_label_train', 'binary_label_train'.
###We could start triplet tranining using Caffe
###press 'Q' to start
###When all images are created in images_all folder as a collection of training images for network tranining and as a gallery of reference images for the classification part, then proceed on.
###After this demo, the binary files of images and labels will be stored as 'binary_image' and 'binary_label' in current path, you should copy them into the leveldb folder in Caffe triplet training, for example: copy these 2 files in <caffe_source_directory>/data/linemod and rename them as 'binary_image_train', 'binary_image_test' and 'binary_label_train', 'binary_label_train'. Here I use the same as trianing and testing data, you can use different data for training and testing the performance in the CAFFE training process. It's important to observe the loss of testing data to check whether training data is suitable for the your aim. Loss should be obseved as keep decreasing and remain on a much smaller number than the initial loss.
###You could start triplet tranining using Caffe like this:
```
$ cd
$ cd <caffe_source_directory>
$ ./examples/triplet/create_3d_triplet.sh
$ ./examples/triplet/train_3d_triplet.sh
```
###After doing this, you will get .caffemodel files as the trained net work. I have already provide the net definition .prototxt files and the trained .caffemodel in <opencv_contrib>/modules/cnn_3dobj/samples/build folder, you could just use them without training in caffe. If you are not interested on feature analysis with the help of binary files provided in Demo2, just skip to Demo3 for feature extraction or Demo4 for classifier.
###After doing this, you will get .caffemodel files as the trained parameter of net work. I have already provide the net definition .prototxt files and the pretrained .caffemodel in <opencv_contrib>/modules/cnn_3dobj/samples/build/data folder, you could just use them without training in caffe.
==============
#Demo4:
##Demo2: feature extraction and classification
```
$ cd
$ cd <opencv_contrib>/modules/cnn_3dobj/samples/build
```
###Classifier, this will extracting the feature of a single image and compare it with features of gallery samples for prediction. Demo2 should be used in advance to generate a file name list for the prediction list. This demo uses a set of images for feature extraction in a given path, these features will be a reference for prediction on target image. Just run:
###Classifier, this will extracting the feature of a single image and compare it with features of gallery samples for prediction. This demo uses a set of images for feature extraction in a given path, these features will be a reference for prediction on target image. Just run:
```
$ ./classify_test
```

@ -90,92 +90,93 @@ namespace cnn_3dobj
/** @brief Icosohedron based camera view generator.
The class create some sphere views of camera towards a 3D object meshed from .ply files @cite hinterstoisser2008panter .
*/
class CV_EXPORTS_W IcoSphere
{
private:
float X;
float Z;
public:
std::vector<float> vertexNormalsList;
std::vector<float> vertexList;
std::vector<cv::Point3d> CameraPos;
std::vector<cv::Point3d> CameraPos_temp;
float radius;
float diff;
IcoSphere(float radius_in, int depth_in);
/** @brief Make all view points having the some distance from the focal point used by the camera view.
*/
CV_WRAP void norm(float v[]);
/** @brief Add new view point between 2 point of the previous view point.
*/
CV_WRAP void add(float v[]);
/** @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, int x, int y, int z);
/** @brief Write binary files used for training in other open source project.
*/
};
class CV_EXPORTS_W Feature
{
private:
caffe::Net<float>* net_;
cv::Size input_geometry_;
int num_channels_;
cv::Mat mean_;
std::vector<string> labels_;
void SetMean(const string& mean_file);
/** @brief Load the mean file in binaryproto format.
*/
void WrapInputLayer(std::vector<cv::Mat>* input_channels);
/** @brief Wrap the input layer of the network in separate cv::Mat objects(one per channel). This way we save one memcpy operation and we don't need to rely on cudaMemcpy2D. The last preprocessing operation will write the separate channels directly to the input layer.
*/
void Preprocess(const cv::Mat& img, std::vector<cv::Mat>* input_channels, bool mean_subtract);
/** @brief Convert the input image to the input image format of the network.
*/
public:
Feature();
void list_dir(const char *path,std::vector<string>& files,bool r);
/** @brief Get the file name from a root dictionary.
*/
void NetSetter(const string& model_file, const string& trained_file, const string& mean_file, const string& cpu_only, int device_id);
/** @brief Initiate a classification structure.
*/
void GetLabellist(const std::vector<string>& name_gallery);
/** @brief Get the label of the gallery images for result displaying in prediction.
*/
std::vector<std::pair<string, float> > Classify(const cv::Mat& reference, const cv::Mat& target, int N);
/** @brief Make a classification.
*/
void FeatureExtract(InputArray inputimg, OutputArray feature, bool mean_subtract, std::string feature_blob);
/** @brief Extract a single featrue of one image.
*/
std::vector<int> Argmax(const std::vector<float>& v, int N);
/** @brief Find the N largest number.
*/
};
//! @}
}}
*/
class CV_EXPORTS_W IcoSphere
{
private:
float X;
float Z;
public:
std::vector<float> vertexNormalsList;
std::vector<float> vertexList;
std::vector<cv::Point3d> CameraPos;
std::vector<cv::Point3d> CameraPos_temp;
float radius;
float diff;
IcoSphere(float radius_in, int depth_in);
/** @brief Make all view points having the some distance from the focal point used by the camera view.
*/
CV_WRAP void norm(float v[]);
/** @brief Add new view point between 2 point of the previous view point.
*/
CV_WRAP void add(float v[]);
/** @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, int x, int y, int z);
/** @brief Write binary files used for training in other open source project.
*/
};
class CV_EXPORTS_W DescriptorExtractor
{
private:
caffe::Net<float>* net_;
cv::Size input_geometry_;
int num_channels_;
cv::Mat mean_;
std::vector<string> labels_;
void SetMean(const string& mean_file);
/** @brief Load the mean file in binaryproto format.
*/
void WrapInputLayer(std::vector<cv::Mat>* input_channels);
/** @brief Wrap the input layer of the network in separate cv::Mat objects(one per channel). This way we save one memcpy operation and we don't need to rely on cudaMemcpy2D. The last preprocessing operation will write the separate channels directly to the input layer.
*/
void Preprocess(const cv::Mat& img, std::vector<cv::Mat>* input_channels, bool mean_subtract);
/** @brief Convert the input image to the input image format of the network.
*/
public:
DescriptorExtractor();
void list_dir(const char *path,std::vector<string>& files,bool r);
/** @brief Get the file name from a root dictionary.
*/
bool SetNet(const string& cpu_only, int device_id);
/** @brief Initiate a classification structure.
*/
bool LoadNet(bool netsetter, const string& model_file, const string& trained_file, const string& mean_file);
/** @brief Initiate a classification structure.
*/
void GetLabellist(const std::vector<string>& name_gallery);
/** @brief Get the label of the gallery images for result displaying in prediction.
*/
std::vector<std::pair<string, float> > Classify(const cv::Mat& reference, const cv::Mat& target, int N);
/** @brief Make a classification.
*/
void Extract(bool net_ready, InputArray inputimg, OutputArray feature, bool mean_subtract, std::string feature_blob);
/** @brief Extract a single featrue of one image.
*/
std::vector<int> Argmax(const std::vector<float>& v, int N);
/** @brief Find the N largest number.
*/
};
//! @}
}
}

@ -0,0 +1,5 @@
#ifndef __OPENCV_CNN_3DOBJ_CONFIG_HPP__
#define __OPENCV_CNN_3DOBJ_CONFIG_HPP__
// HAVE CAFFE
#define HAVE_CAFFE
#endif

@ -67,11 +67,12 @@ int main(int argc, char** argv)
string device = parser.get<string>("device");
int dev_id = parser.get<int>("dev_id");
cv::cnn_3dobj::Classification classifier;
classifier.NetSetter(network_forIMG, caffemodel, mean_file, device, dev_id);
cv::cnn_3dobj::DescriptorExtractor descriptor;
bool set_succeed = descriptor.SetNet(device, dev_id);
descriptor.LoadNet(set_succeed, network_forIMG, caffemodel, mean_file);
std::vector<string> name_gallery;
classifier.list_dir(src_dir.c_str(), name_gallery, false);
classifier.GetLabellist(name_gallery);
descriptor.list_dir(src_dir.c_str(), name_gallery, false);
descriptor.GetLabellist(name_gallery);
for (unsigned int i = 0; i < name_gallery.size(); i++) {
name_gallery[i] = src_dir + name_gallery[i];
}
@ -80,7 +81,7 @@ int main(int argc, char** argv)
for (unsigned int i = 0; i < name_gallery.size(); i++) {
img_gallery.push_back(cv::imread(name_gallery[i], -1));
}
classifier.FeatureExtract(img_gallery, feature_reference, false, feature_blob);
descriptor.FeatureExtract(img_gallery, feature_reference, false, feature_blob);
std::cout << std::endl << "---------- Prediction for "
<< target_img << " ----------" << std::endl;
@ -92,9 +93,9 @@ int main(int argc, char** argv)
for (unsigned int i = 0; i < feature_reference.rows; i++)
std::cout << feature_reference.row(i) << endl;
cv::Mat feature_test;
classifier.FeatureExtract(img, feature_test, false, feature_blob);
descriptor.FeatureExtract(img, feature_test, false, feature_blob);
std::cout << std::endl << "---------- Featrue of target image: " << target_img << "----------" << endl << feature_test << std::endl;
prediction = classifier.Classify(feature_reference, feature_test, num_candidate);
prediction = descriptor.Classify(feature_reference, feature_test, num_candidate);
// Print the top N prediction.
std::cout << std::endl << "---------- Prediction result(Distance - File Name in Gallery) ----------" << std::endl;
for (size_t i = 0; i < prediction.size(); ++i) {

@ -6,234 +6,265 @@ namespace cv
{
namespace cnn_3dobj
{
Feature::Feature(){};
void Feature::list_dir(const char *path,vector<string>& files,bool r)
{
DIR *pDir;
struct dirent *ent;
char childpath[512];
pDir = opendir(path);
memset(childpath, 0, sizeof(childpath));
while ((ent = readdir(pDir)) != NULL)
DescriptorExtractor::DescriptorExtractor(){};
void DescriptorExtractor::list_dir(const char *path,vector<string>& files,bool r)
{
if (ent->d_type & DT_DIR)
{
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
DIR *pDir;
struct dirent *ent;
char childpath[512];
pDir = opendir(path);
memset(childpath, 0, sizeof(childpath));
while ((ent = readdir(pDir)) != NULL)
{
continue;
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);
DescriptorExtractor::list_dir(childpath,files,false);
}
}
else
{
files.push_back(ent->d_name);
}
}
if(r)
sort(files.begin(),files.end());
};
bool DescriptorExtractor::SetNet(const string& cpu_only, int device_id)
{
if (strcmp(cpu_only.c_str(), "CPU") == 0 || strcmp(cpu_only.c_str(), "GPU") == 0)
{
if (strcmp(cpu_only.c_str(), "CPU") == 0)
{
caffe::Caffe::set_mode(caffe::Caffe::CPU);
}
else
{
caffe::Caffe::set_mode(caffe::Caffe::GPU);
caffe::Caffe::SetDevice(device_id);
std::cout << "Using Device_id=" << device_id << std::endl;
}
return true;
}
else
{
sprintf(childpath, "%s/%s", path, ent->d_name);
Feature::list_dir(childpath,files,false);
std::cout << "Error: Device name must be 'GPU' together with an device number or 'CPU'." << std::endl;
return false;
}
}
else
{
files.push_back(ent->d_name);
}
}
sort(files.begin(),files.end());
};
};
void Feature::NetSetter(const string& model_file, const string& trained_file, const string& mean_file, const string& cpu_only, int device_id)
{
if (strcmp(cpu_only.c_str(), "CPU") == 0)
{
caffe::Caffe::set_mode(caffe::Caffe::CPU);
}
else
bool DescriptorExtractor::LoadNet(bool netsetter, const string& model_file, const string& trained_file, const string& mean_file)
{
caffe::Caffe::set_mode(caffe::Caffe::GPU);
caffe::Caffe::SetDevice(device_id);
}
/* Load the network. */
net_ = new Net<float>(model_file, TEST);
net_->CopyTrainedLayersFrom(trained_file);
CHECK_EQ(net_->num_inputs(), 1) << "Network should have exactly one input.";
CHECK_EQ(net_->num_outputs(), 1) << "Network should have exactly one output.";
Blob<float>* input_layer = net_->input_blobs()[0];
num_channels_ = input_layer->channels();
CHECK(num_channels_ == 3 || num_channels_ == 1)
<< "Input layer should have 1 or 3 channels.";
input_geometry_ = cv::Size(input_layer->width(), input_layer->height());
/* Load the binaryproto mean file. */
SetMean(mean_file);
};
void Feature::GetLabellist(const std::vector<string>& name_gallery)
{
for (unsigned int i = 0; i < name_gallery.size(); ++i)
labels_.push_back(name_gallery[i]);
};
bool net_ready = false;
if (netsetter)
{
/* Load the network. */
net_ = new Net<float>(model_file, TEST);
net_->CopyTrainedLayersFrom(trained_file);
if (net_->num_inputs() != 1)
std::cout << "Network should have exactly one input." << std::endl;
if (net_->num_outputs() != 1)
std::cout << "Network should have exactly one output." << std::endl;
Blob<float>* input_layer = net_->input_blobs()[0];
num_channels_ = input_layer->channels();
if (num_channels_ != 3 && num_channels_ != 1)
std::cout << "Input layer should have 1 or 3 channels." << std::endl;
input_geometry_ = cv::Size(input_layer->width(), input_layer->height());
/* Load the binaryproto mean file. */
SetMean(mean_file);
net_ready = true;
return net_ready;
}
else
{
std::cout << "Error: Device must be set in advance using SetNet function" << std::endl;
return net_ready;
}
};
/* Return the indices of the top N values of vector v. */
std::vector<int> Feature::Argmax(const std::vector<float>& v, int N)
{
std::vector<std::pair<float, int> > pairs;
for (size_t i = 0; i < v.size(); ++i)
pairs.push_back(std::make_pair(v[i], i));
std::partial_sort(pairs.begin(), pairs.begin() + N, pairs.end());
std::vector<int> result;
for (int i = 0; i < N; ++i)
result.push_back(pairs[i].second);
return result;
};
void DescriptorExtractor::GetLabellist(const std::vector<string>& name_gallery)
{
for (unsigned int i = 0; i < name_gallery.size(); ++i)
labels_.push_back(name_gallery[i]);
};
//Return the top N predictions.
std::vector<std::pair<string, float> > Feature::Classify(const cv::Mat& reference, const cv::Mat& target, int N)
{
std::vector<float> output;
for (int i = 0; i < reference.rows; i++)
/* Return the indices of the top N values of vector v. */
std::vector<int> DescriptorExtractor::Argmax(const std::vector<float>& v, int N)
{
cv::Mat f1 = reference.row(i);
cv::Mat f2 = target;
cv::Mat output_temp = f1-f2;
output.push_back(cv::norm(output_temp));
}
std::vector<int> maxN = Argmax(output, N);
std::vector<std::pair<string, float> > predictions;
for (int i = 0; i < N; ++i)
std::vector<std::pair<float, int> > pairs;
for (size_t i = 0; i < v.size(); ++i)
pairs.push_back(std::make_pair(v[i], i));
std::partial_sort(pairs.begin(), pairs.begin() + N, pairs.end());
std::vector<int> result;
for (int i = 0; i < N; ++i)
result.push_back(pairs[i].second);
return result;
};
std::vector<std::pair<string, float> > DescriptorExtractor::Classify(const cv::Mat& reference, const cv::Mat& target, int N)
{
int idx = maxN[i];
predictions.push_back(std::make_pair(labels_[idx], output[idx]));
}
return predictions;
};
std::vector<float> output;
for (int i = 0; i < reference.rows; i++)
{
cv::Mat f1 = reference.row(i);
cv::Mat f2 = target;
cv::Mat output_temp = f1-f2;
output.push_back(cv::norm(output_temp));
}
std::vector<int> maxN = Argmax(output, N);
std::vector<std::pair<string, float> > predictions;
for (int i = 0; i < N; ++i)
{
int idx = maxN[i];
predictions.push_back(std::make_pair(labels_[idx], output[idx]));
}
return predictions;
};
/* Load the mean file in binaryproto format. */
void Feature::SetMean(const string& mean_file)
{
BlobProto blob_proto;
ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
/* Convert from BlobProto to Blob<float> */
Blob<float> mean_blob;
mean_blob.FromProto(blob_proto);
CHECK_EQ(mean_blob.channels(), num_channels_)
<< "Number of channels of mean file doesn't match input layer.";
/* The format of the mean file is planar 32-bit float BGR or grayscale. */
std::vector<cv::Mat> channels;
float* data = mean_blob.mutable_cpu_data();
for (int i = 0; i < num_channels_; ++i)
/* Load the mean file in binaryproto format. */
void DescriptorExtractor::SetMean(const string& mean_file)
{
/* Extract an individual channel. */
cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
channels.push_back(channel);
data += mean_blob.height() * mean_blob.width();
}
/* Merge the separate channels into a single image. */
cv::Mat mean;
cv::merge(channels, mean);
/* Compute the global mean pixel value and create a mean image
* filled with this value. */
cv::Scalar channel_mean = cv::mean(mean);
mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean);
};
BlobProto blob_proto;
ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
/* Convert from BlobProto to Blob<float> */
Blob<float> mean_blob;
mean_blob.FromProto(blob_proto);
if (mean_blob.channels() != num_channels_)
std::cout << "Number of channels of mean file doesn't match input layer." << std::endl;
/* The format of the mean file is planar 32-bit float BGR or grayscale. */
std::vector<cv::Mat> channels;
float* data = mean_blob.mutable_cpu_data();
for (int i = 0; i < num_channels_; ++i)
{
/* Extract an individual channel. */
cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
channels.push_back(channel);
data += mean_blob.height() * mean_blob.width();
}
/* Merge the separate channels into a single image. */
cv::Mat mean;
cv::merge(channels, mean);
/* Compute the global mean pixel value and create a mean image
* filled with this value. */
cv::Scalar channel_mean = cv::mean(mean);
mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean);
};
void Feature::FeatureExtract(InputArray inputimg, OutputArray feature, bool mean_subtract, std::string featrue_blob)
{
Blob<float>* input_layer = net_->input_blobs()[0];
input_layer->Reshape(1, num_channels_,
input_geometry_.height, input_geometry_.width);
/* Forward dimension change to all layers. */
net_->Reshape();
std::vector<cv::Mat> input_channels;
WrapInputLayer(&input_channels);
if (inputimg.kind() == 65536)
{/* this is a Mat */
Mat img = inputimg.getMat();
Preprocess(img, &input_channels, mean_subtract);
net_->ForwardPrefilled();
/* Copy the output layer to a std::vector */
Blob<float>* output_layer = net_->blob_by_name(featrue_blob).get();
const float* begin = output_layer->cpu_data();
const float* end = begin + output_layer->channels();
std::vector<float> featureVec = std::vector<float>(begin, end);
cv::Mat feature_mat = cv::Mat(featureVec, true).t();
feature_mat.copyTo(feature);
}
else
{/* This is a vector<Mat> */
vector<Mat> img;
inputimg.getMatVector(img);
Mat feature_vector;
for (unsigned int i = 0; i < img.size(); ++i)
{
Preprocess(img[i], &input_channels, mean_subtract);
net_->ForwardPrefilled();
/* Copy the output layer to a std::vector */
Blob<float>* output_layer = net_->blob_by_name(featrue_blob).get();
const float* begin = output_layer->cpu_data();
const float* end = begin + output_layer->channels();
std::vector<float> featureVec = std::vector<float>(begin, end);
if (i == 0)
void DescriptorExtractor::Extract(bool net_ready, InputArray inputimg, OutputArray feature, bool mean_subtract, std::string featrue_blob)
{
if (net_ready)
{
feature_vector = cv::Mat(featureVec, true).t();
int dim_feature = feature_vector.cols;
feature_vector.resize(img.size(), dim_feature);
Blob<float>* input_layer = net_->input_blobs()[0];
input_layer->Reshape(1, num_channels_,
input_geometry_.height, input_geometry_.width);
/* Forward dimension change to all layers. */
net_->Reshape();
std::vector<cv::Mat> input_channels;
WrapInputLayer(&input_channels);
if (inputimg.kind() == 65536)
{/* this is a Mat */
Mat img = inputimg.getMat();
Preprocess(img, &input_channels, mean_subtract);
net_->ForwardPrefilled();
/* Copy the output layer to a std::vector */
Blob<float>* output_layer = net_->blob_by_name(featrue_blob).get();
const float* begin = output_layer->cpu_data();
const float* end = begin + output_layer->channels();
std::vector<float> featureVec = std::vector<float>(begin, end);
cv::Mat feature_mat = cv::Mat(featureVec, true).t();
feature_mat.copyTo(feature);
}
else
{/* This is a vector<Mat> */
vector<Mat> img;
inputimg.getMatVector(img);
Mat feature_vector;
for (unsigned int i = 0; i < img.size(); ++i)
{
Preprocess(img[i], &input_channels, mean_subtract);
net_->ForwardPrefilled();
/* Copy the output layer to a std::vector */
Blob<float>* output_layer = net_->blob_by_name(featrue_blob).get();
const float* begin = output_layer->cpu_data();
const float* end = begin + output_layer->channels();
std::vector<float> featureVec = std::vector<float>(begin, end);
if (i == 0)
{
feature_vector = cv::Mat(featureVec, true).t();
int dim_feature = feature_vector.cols;
feature_vector.resize(img.size(), dim_feature);
}
feature_vector.row(i) = cv::Mat(featureVec, true).t();
}
feature_vector.copyTo(feature);
}
}
feature_vector.row(i) = cv::Mat(featureVec, true).t();
}
feature_vector.copyTo(feature);
}
};
else
std::cout << "Network must be set properly using SetNet and LoadNet in advance.";
};
/* Wrap the input layer of the network in separate cv::Mat objects
* (one per channel). This way we save one memcpy operation and we
* don't need to rely on cudaMemcpy2D. The last preprocessing
* operation will write the separate channels directly to the input
* layer. */
void Feature::WrapInputLayer(std::vector<cv::Mat>* input_channels)
{
Blob<float>* input_layer = net_->input_blobs()[0];
int width = input_layer->width();
int height = input_layer->height();
float* input_data = input_layer->mutable_cpu_data();
for (int i = 0; i < input_layer->channels(); ++i)
/* Wrap the input layer of the network in separate cv::Mat objects
* (one per channel). This way we save one memcpy operation and we
* don't need to rely on cudaMemcpy2D. The last preprocessing
* operation will write the separate channels directly to the input
* layer. */
void DescriptorExtractor::WrapInputLayer(std::vector<cv::Mat>* input_channels)
{
cv::Mat channel(height, width, CV_32FC1, input_data);
input_channels->push_back(channel);
input_data += width * height;
}
};
Blob<float>* input_layer = net_->input_blobs()[0];
int width = input_layer->width();
int height = input_layer->height();
float* input_data = input_layer->mutable_cpu_data();
for (int i = 0; i < input_layer->channels(); ++i)
{
cv::Mat channel(height, width, CV_32FC1, input_data);
input_channels->push_back(channel);
input_data += width * height;
}
};
void Feature::Preprocess(const cv::Mat& img,
void DescriptorExtractor::Preprocess(const cv::Mat& img,
std::vector<cv::Mat>* input_channels, bool mean_subtract)
{
/* Convert the input image to the input image format of the network. */
cv::Mat sample;
if (img.channels() == 3 && num_channels_ == 1)
cv::cvtColor(img, sample, CV_BGR2GRAY);
else if (img.channels() == 4 && num_channels_ == 1)
cv::cvtColor(img, sample, CV_BGRA2GRAY);
else if (img.channels() == 4 && num_channels_ == 3)
cv::cvtColor(img, sample, CV_BGRA2BGR);
else if (img.channels() == 1 && num_channels_ == 3)
cv::cvtColor(img, sample, CV_GRAY2BGR);
else
sample = img;
cv::Mat sample_resized;
if (sample.size() != input_geometry_)
cv::resize(sample, sample_resized, input_geometry_);
else
sample_resized = sample;
cv::Mat sample_float;
if (num_channels_ == 3)
sample_resized.convertTo(sample_float, CV_32FC3);
else
sample_resized.convertTo(sample_float, CV_32FC1);
cv::Mat sample_normalized;
if (mean_subtract)
cv::subtract(sample_float, mean_, sample_normalized);
else
sample_normalized = sample_float;
/* This operation will write the separate BGR planes directly to the
* input layer of the network because it is wrapped by the cv::Mat
* objects in input_channels. */
cv::split(sample_normalized, *input_channels);
CHECK(reinterpret_cast<float*>(input_channels->at(0).data)
== net_->input_blobs()[0]->cpu_data())
<< "Input channels are not wrapping the input layer of the network.";
};
{
/* Convert the input image to the input image format of the network. */
cv::Mat sample;
if (img.channels() == 3 && num_channels_ == 1)
cv::cvtColor(img, sample, CV_BGR2GRAY);
else if (img.channels() == 4 && num_channels_ == 1)
cv::cvtColor(img, sample, CV_BGRA2GRAY);
else if (img.channels() == 4 && num_channels_ == 3)
cv::cvtColor(img, sample, CV_BGRA2BGR);
else if (img.channels() == 1 && num_channels_ == 3)
cv::cvtColor(img, sample, CV_GRAY2BGR);
else
sample = img;
cv::Mat sample_resized;
if (sample.size() != input_geometry_)
cv::resize(sample, sample_resized, input_geometry_);
else
sample_resized = sample;
cv::Mat sample_float;
if (num_channels_ == 3)
sample_resized.convertTo(sample_float, CV_32FC3);
else
sample_resized.convertTo(sample_float, CV_32FC1);
cv::Mat sample_normalized;
if (mean_subtract)
cv::subtract(sample_float, mean_, sample_normalized);
else
sample_normalized = sample_float;
/* This operation will write the separate BGR planes directly to the
* input layer of the network because it is wrapped by the cv::Mat
* objects in input_channels. */
cv::split(sample_normalized, *input_channels);
if (reinterpret_cast<float*>(input_channels->at(0).data)
!= net_->input_blobs()[0]->cpu_data())
std::cout << "Input channels are not wrapping the input layer of the network." << std::endl;
};
}
}

@ -6,230 +6,230 @@ namespace cv
{
namespace cnn_3dobj
{
IcoSphere::IcoSphere(float radius_in, int depth_in)
{
IcoSphere::IcoSphere(float radius_in, int depth_in)
{
X = 0.5f;
Z = 0.5f;
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 },
{ 0.0f, -Z, X }, { 0.0f, -Z, -X }, { Z, X, 0.0f }, { -Z, X, 0.0f },
{ Z, -X, 0.0f }, { -Z, -X, 0.0f } };
int tindices[20][3] = { { 0, 4, 1 }, { 0, 9, 4 }, { 9, 5, 4 },
{ 4, 5, 8 }, { 4, 8, 1 }, { 8, 10, 1 }, { 8, 3, 10 }, { 5, 3, 8 },
{ 5, 2, 3 }, { 2, 7, 3 }, { 7, 10, 3 }, { 7, 6, 10 }, { 7, 11, 6 },
{ 11, 0, 6 }, { 0, 1, 6 }, { 6, 1, 10 }, { 9, 0, 11 },
{ 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 } };
X = 0.5f;
Z = 0.5f;
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 },
{ 0.0f, -Z, X }, { 0.0f, -Z, -X }, { Z, X, 0.0f }, { -Z, X, 0.0f },
{ Z, -X, 0.0f }, { -Z, -X, 0.0f } };
int tindices[20][3] = { { 0, 4, 1 }, { 0, 9, 4 }, { 9, 5, 4 },
{ 4, 5, 8 }, { 4, 8, 1 }, { 8, 10, 1 }, { 8, 3, 10 }, { 5, 3, 8 },
{ 5, 2, 3 }, { 2, 7, 3 }, { 7, 10, 3 }, { 7, 6, 10 }, { 7, 11, 6 },
{ 11, 0, 6 }, { 0, 1, 6 }, { 6, 1, 10 }, { 9, 0, 11 },
{ 9, 11, 2 }, { 9, 2, 5 }, { 7, 2, 11 } };
// Iterate over points
for (int i = 0; i < 20; ++i)
{
subdivide(vdata[tindices[i][0]], vdata[tindices[i][1]],
vdata[tindices[i][2]], depth_in);
}
CameraPos_temp.push_back(CameraPos[0]);
for (int j = 1; j<int(CameraPos.size()); j++)
{
for (int k = 0; k<j; k++)
{
if (CameraPos.at(k).x-CameraPos.at(j).x<diff && CameraPos.at(k).y-CameraPos.at(j).y<diff && CameraPos.at(k).z-CameraPos.at(j).z<diff)
break;
if(k == j-1)
CameraPos_temp.push_back(CameraPos[j]);
}
}
CameraPos = CameraPos_temp;
cout << "View points in total: " << CameraPos.size() << endl;
cout << "The coordinate of view point: " << endl;
for(int i=0; i < (int)CameraPos.size(); i++)
{
cout << CameraPos.at(i).x <<' '<< CameraPos.at(i).y << ' ' << CameraPos.at(i).z << endl;
}
};
void IcoSphere::norm(float v[])
{
float len = 0;
for (int i = 0; i < 3; ++i)
{
len += v[i] * v[i];
}
len = sqrt(len);
for (int i = 0; i < 3; ++i)
// Iterate over points
for (int i = 0; i < 20; ++i)
{
subdivide(vdata[tindices[i][0]], vdata[tindices[i][1]],
vdata[tindices[i][2]], depth_in);
}
CameraPos_temp.push_back(CameraPos[0]);
for (int j = 1; j<int(CameraPos.size()); j++)
{
for (int k = 0; k<j; k++)
{
if (CameraPos.at(k).x-CameraPos.at(j).x<diff && CameraPos.at(k).y-CameraPos.at(j).y<diff && CameraPos.at(k).z-CameraPos.at(j).z<diff)
break;
if(k == j-1)
CameraPos_temp.push_back(CameraPos[j]);
}
}
CameraPos = CameraPos_temp;
cout << "View points in total: " << CameraPos.size() << endl;
cout << "The coordinate of view point: " << endl;
for(int i=0; i < (int)CameraPos.size(); i++)
{
cout << CameraPos.at(i).x <<' '<< CameraPos.at(i).y << ' ' << CameraPos.at(i).z << endl;
}
};
void IcoSphere::norm(float v[])
{
v[i] /= ((float)len);
}
};
float len = 0;
for (int i = 0; i < 3; ++i)
{
len += v[i] * v[i];
}
len = sqrt(len);
for (int i = 0; i < 3; ++i)
{
v[i] /= ((float)len);
}
};
void IcoSphere::add(float v[])
{
Point3f temp_Campos;
std::vector<float>* temp = new std::vector<float>;
for (int k = 0; k < 3; ++k)
void IcoSphere::add(float v[])
{
vertexList.push_back(v[k]);
vertexNormalsList.push_back(v[k]);
temp->push_back(v[k]);
}
temp_Campos.x = temp->at(0);temp_Campos.y = temp->at(1);temp_Campos.z = temp->at(2);
CameraPos.push_back(temp_Campos);
};
Point3f temp_Campos;
std::vector<float>* temp = new std::vector<float>;
for (int k = 0; k < 3; ++k)
{
vertexList.push_back(v[k]);
vertexNormalsList.push_back(v[k]);
temp->push_back(v[k]);
}
temp_Campos.x = temp->at(0);temp_Campos.y = temp->at(1);temp_Campos.z = temp->at(2);
CameraPos.push_back(temp_Campos);
};
void IcoSphere::subdivide(float v1[], float v2[], float v3[], int depth)
{
norm(v1);
norm(v2);
norm(v3);
if (depth == 0)
void IcoSphere::subdivide(float v1[], float v2[], float v3[], int depth)
{
add(v1);
add(v2);
add(v3);
return;
}
float* v12 = new float[3];
float* v23 = new float[3];
float* v31 = new float[3];
for (int i = 0; i < 3; ++i)
{
v12[i] = (v1[i] + v2[i]) / 2;
v23[i] = (v2[i] + v3[i]) / 2;
v31[i] = (v3[i] + v1[i]) / 2;
}
norm(v12);
norm(v23);
norm(v31);
subdivide(v1, v12, v31, depth - 1);
subdivide(v2, v23, v12, depth - 1);
subdivide(v3, v31, v23, 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);
};
norm(v1);
norm(v2);
norm(v3);
if (depth == 0)
{
add(v1);
add(v2);
add(v3);
return;
}
float* v12 = new float[3];
float* v23 = new float[3];
float* v31 = new float[3];
for (int i = 0; i < 3; ++i)
{
v12[i] = (v1[i] + v2[i]) / 2;
v23[i] = (v2[i] + v3[i]) / 2;
v31[i] = (v3[i] + v1[i]) / 2;
}
norm(v12);
norm(v23);
norm(v31);
subdivide(v1, v12, v31, depth - 1);
subdivide(v2, v23, v12, depth - 1);
subdivide(v3, v31, v23, depth - 1);
subdivide(v12, v23, v31, depth - 1);
};
cv::Point3d IcoSphere::getCenter(cv::Mat cloud)
{
Point3f* data = cloud.ptr<cv::Point3f>();
Point3d dataout;
for(int i = 0; i < cloud.cols; ++i)
uint32_t IcoSphere::swap_endian(uint32_t val)
{
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;
};
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
return (val << 16) | (val >> 16);
};
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)
cv::Point3d IcoSphere::getCenter(cv::Mat cloud)
{
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;
};
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;
};
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] = {2050,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();
};
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::writeBinaryfile(string filenameImg, const char* binaryPath, const char* headerPath, int num_item, int label_class, int x, int y, int z)
{
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)
void IcoSphere::createHeader(int num_item, int rows, int cols, const char* headerPath)
{
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());
}
signed char templab = (signed char)label_class;
lab_file << templab << (signed char)x << (signed char)y << (signed char)z;
}
else
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] = {2050,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 x, int y, int z)
{
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());
}
signed char templab = (signed char)label_class;
lab_file << templab << (signed char)x << (signed char)y << (signed char)z;
}
img_file.close();
lab_file.close();
};
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());
}
signed char templab = (signed char)label_class;
lab_file << templab << (signed char)x << (signed char)y << (signed char)z;
}
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());
}
signed char templab = (signed char)label_class;
lab_file << templab << (signed char)x << (signed char)y << (signed char)z;
}
img_file.close();
lab_file.close();
};
}}

Loading…
Cancel
Save