Merge pull request #276 from Wangyida:cnn_3dobj

pull/446/head
Vadim Pisarevsky 10 years ago
commit 5e008c8758
  1. 2
      modules/README.md
  2. 42
      modules/cnn_3dobj/CMakeLists.txt
  3. 14
      modules/cnn_3dobj/FindCaffe.cmake
  4. 10
      modules/cnn_3dobj/FindGlog.cmake
  5. 10
      modules/cnn_3dobj/FindProtobuf.cmake
  6. 112
      modules/cnn_3dobj/README.md
  7. 5
      modules/cnn_3dobj/cnn_3dobj_config.hpp.in
  8. 13
      modules/cnn_3dobj/doc/cnn_3dobj.bib
  9. 291
      modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp
  10. 0
      modules/cnn_3dobj/include/opencv2/cnn_3dobj_config.hpp
  11. 21
      modules/cnn_3dobj/samples/CMakeLists.txt
  12. 1408
      modules/cnn_3dobj/samples/data/3Dmodel/ant.ply
  13. 17534
      modules/cnn_3dobj/samples/data/3Dmodel/ape.ply
  14. 105411
      modules/cnn_3dobj/samples/data/3Dmodel/bunny.ply
  15. 8717
      modules/cnn_3dobj/samples/data/3Dmodel/cow.ply
  16. BIN
      modules/cnn_3dobj/samples/data/3Dmodel/horse.ply
  17. 3797
      modules/cnn_3dobj/samples/data/3Dmodel/plane.ply
  18. BIN
      modules/cnn_3dobj/samples/data/images_mean/triplet_mean.binaryproto
  19. 0
      modules/cnn_3dobj/samples/data/label_all.txt
  20. 91
      modules/cnn_3dobj/samples/datagen_all.sh
  21. 45
      modules/cnn_3dobj/samples/datagen_back.sh
  22. 60
      modules/cnn_3dobj/samples/datagen_front.sh
  23. 201
      modules/cnn_3dobj/samples/demo_classify.cpp
  24. 155
      modules/cnn_3dobj/samples/demo_model_analysis.cpp
  25. 333
      modules/cnn_3dobj/samples/demo_sphereview_data.cpp
  26. 391
      modules/cnn_3dobj/samples/demo_video.cpp
  27. 1
      modules/cnn_3dobj/samples/featstore.sh
  28. 259
      modules/cnn_3dobj/src/cnn_feature.cpp
  29. 265
      modules/cnn_3dobj/src/cnn_sphereview.cpp
  30. 47
      modules/cnn_3dobj/src/precomp.hpp
  31. 63
      modules/cnn_3dobj/test/test_cnn_3dobj_feature_extract.cpp
  32. 3
      modules/cnn_3dobj/test/test_main.cpp
  33. 18
      modules/cnn_3dobj/test/test_precomp.hpp
  34. BIN
      modules/cnn_3dobj/testdata/cv/3d_triplet_iter_30000.caffemodel
  35. 86
      modules/cnn_3dobj/testdata/cv/3d_triplet_testIMG.prototxt
  36. BIN
      modules/cnn_3dobj/testdata/cv/4_78.png
  37. 52
      modules/cnn_3dobj/testdata/cv/caffemodel_list.txt
  38. 75
      modules/cnn_3dobj/tutorials/data_generation/data_generation.markdown
  39. 66
      modules/cnn_3dobj/tutorials/feature_classification/classify.markdown
  40. 60
      modules/cnn_3dobj/tutorials/model_analysis/model_analysis.markdown
  41. 26
      modules/cnn_3dobj/tutorials/table_of_content_cnn_3dobj.markdown

@ -47,7 +47,7 @@ $ cmake -D OPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules -D BUILD_opencv_re
19. **opencv_xfeatures2d**: Extra 2D Features Framework containing experimental and non-free 2D feature algorithms.
20. **opencv_ximgproc**: Extended Image Processing: Structured Forests / Domain Transform Filter / Guided Filter / Adaptive Manifold Filter / Joint Bilateral Filter / Superpixels.
21. **opencv_xobjdetect**: Integral Channel Features Detector Framework.
22. **opencv_xphoto**: Additional photo processing algorithms: Color balance / Denoising / Inpainting.

@ -0,0 +1,42 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
find_package(Caffe)
if(Caffe_FOUND)
message(STATUS "Caffe: YES")
set(HAVE_CAFFE 1)
else()
message(STATUS "Caffe: NO")
endif()
find_package(Protobuf)
if(Protobuf_FOUND)
message(STATUS "Protobuf: YES")
set(HAVE_PROTOBUF 1)
else()
message(STATUS "Protobuf: NO")
endif()
find_package(Glog)
if(Glog_FOUND)
message(STATUS "Glog: YES")
set(HAVE_GLOG 1)
else()
message(STATUS "Glog: NO")
endif()
if(HAVE_CAFFE)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cnn_3dobj_config.hpp.in
${CMAKE_CURRENT_SOURCE_DIR}/include/opencv2/cnn_3dobj_config.hpp @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(${Caffe_FOUND})
include_directories(${Caffe_INCLUDE_DIR})
endif()
set(the_description "CNN for 3D object recognition and pose estimation including a completed Sphere View on 3D objects")
ocv_define_module(cnn_3dobj opencv_core opencv_imgproc opencv_viz opencv_highgui OPTIONAL WRAP python)
if(${Caffe_FOUND})
target_link_libraries(opencv_cnn_3dobj ${Caffe_LIBS} ${Glog_LIBS} ${Protobuf_LIBS})
endif()
endif()

@ -0,0 +1,14 @@
# Caffe package for CNN Triplet training
unset(Caffe_FOUND)
find_path(Caffe_INCLUDE_DIR NAMES caffe/caffe.hpp caffe/common.hpp caffe/net.hpp caffe/proto/caffe.pb.h caffe/util/io.hpp caffe/vision_layers.hpp
HINTS
/usr/local/include)
find_library(Caffe_LIBS NAMES caffe
HINTS
/usr/local/lib)
if(Caffe_LIBS AND Caffe_INCLUDE_DIR)
set(Caffe_FOUND 1)
endif()

@ -0,0 +1,10 @@
# Glog package for CNN Triplet training
unset(Glog_FOUND)
find_library(Glog_LIBS NAMES glog
HINTS
/usr/local/lib)
if(Glog_LIBS)
set(Glog_FOUND 1)
endif()

@ -0,0 +1,10 @@
# Protobuf package for CNN Triplet training
unset(Protobuf_FOUND)
find_library(Protobuf_LIBS NAMES protobuf
HINTS
/usr/local/lib)
if(Protobuf_LIBS)
set(Protobuf_FOUND 1)
endif()

@ -0,0 +1,112 @@
#Convolutional Neural Network for 3D object classification and pose estimation.
===========================================================
#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(<http://caffe.berkeleyvision.org/>) 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:
<https://github.com/Wangyida/caffe/tree/cnn_triplet>.
####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 -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 protobuf and caffe will be recognized as already installed while building. Protobuf is needed.
#Compiling OpenCV
```
$ cd <opencv_source_directory>
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=OFF -D WITH_OPENGL=ON -D WITH_VTK=ON -D INSTALL_TESTS=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
$ 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
```
$ cd <opencv_contrib>/modules/cnn_3dobj/samples
$ mkdir build
$ cd build
$ cmake ..
$ make
```
===========================================================
#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. If you will train net work and extract feature from RGB images set the parameter rgb_use as 1.
```
$ ./sphereview_test -plymodel=../data/3Dmodel/ape.ply -label_class=0 -cam_head_x=0 -cam_head_y=0 -cam_head_z=1
```
####press 'Q' to start 2D image genaration
```
$ ./sphereview_test -plymodel=../data/3Dmodel/ant.ply -label_class=1 -cam_head_x=0 -cam_head_y=-1 -cam_head_z=0
```
```
$ ./sphereview_test -plymodel=../data/3Dmodel/cow.ply -label_class=2 -cam_head_x=0 -cam_head_y=-1 -cam_head_z=0
```
```
$ ./sphereview_test -plymodel=../data/3Dmodel/plane.ply -label_class=3 -cam_head_x=0 -cam_head_y=-1 -cam_head_z=0
```
```
$ ./sphereview_test -plymodel=../data/3Dmodel/bunny.ply -label_class=4 -cam_head_x=0 -cam_head_y=-1 -cam_head_z=0
```
```
$ ./sphereview_test -plymodel=../data/3Dmodel/horse.ply -label_class=5 -cam_head_x=0 -cam_head_y=0 -cam_head_z=-1
```
####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 parameter of net work. I have already provide the net definition .prototxt files and the pretrained .caffemodel in <opencv_contrib>/modules/cnn_3dobj/testdata/cv folder, you could just use them without training in caffe.
===========================================================
##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. 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. The caffe model and network prototxt file is attached in <opencv_contrib>/modules/cnn_3dobj/testdata/cv. Just run:
```
$ ./classify_test
```
####if the classification and pose estimation issue need to extract mean got from all training images, you can run this:
```
$ ./classify_test -mean_file=../data/images_mean/triplet_mean.binaryproto
```
===========================================================
##Demo3: model performance test
####This demo will have a test on the performance of trained CNN model on several images. If the the model fail on telling different samples from seperate classes or confused on samples with similar pose but from different classes, it will give some information on the model analysis.
```
$ ./model_test
```
===========================================================
#Test
####If you want to have a test on cnn_3dobj module, the path of test data must be set in advance:
```
$ export OPENCV_TEST_DATA_PATH=<opencv_contrib>/modules/cnn_3dobj/testdata
```

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

@ -0,0 +1,13 @@
@Article{hinterstoisser2008panter,
author = {Hinterstoisser, S. and Benhimane, S. and and Lepetit, V. and Navab, N.},
title = {Simultaneous Recognition and Homography Extraction of Local Patches with a Simple Linear Classifier},
booktitle = {BMVC British Machine Vision Conference 2008},
year = {2008}
}
@inproceedings{wohlhart15,
author = {Paul Wohlhart and Vincent Lepetit},
title = {Learning Descriptors for Object Recognition and 3D Pose Estimation},
booktitle = {Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},
year = {2015}
}

@ -0,0 +1,291 @@
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2015, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015, OpenCV Foundation, all rights reserved.
Copyright (C) 2015, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_CNN_3DOBJ_HPP__
#define __OPENCV_CNN_3DOBJ_HPP__
#ifdef __cplusplus
#include <string>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <set>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#define CPU_ONLY
#include <opencv2/cnn_3dobj_config.hpp>
#ifdef HAVE_CAFFE
#include <caffe/blob.hpp>
#include <caffe/common.hpp>
#include <caffe/net.hpp>
#include <caffe/proto/caffe.pb.h>
#include <caffe/util/io.hpp>
#include <caffe/vision_layers.hpp>
#endif
#include "opencv2/viz/vizcore.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc.hpp"
using caffe::Blob;
using caffe::Caffe;
using caffe::Datum;
using caffe::Net;
/** @defgroup cnn_3dobj 3D object recognition and pose estimation API
As CNN based learning algorithm shows better performance on the classification issues,
the rich labeled data could be more useful in the training stage. 3D object classification and pose estimation
is a jointed mission aimming at seperate different posed apart in the descriptor form.
In the training stage, we prepare 2D training images generated from our module with their
class label and pose label. We fully exploit the information lies in their labels
by using a triplet and pair-wise jointed loss function in CNN training.
As CNN based learning algorithm shows better performance on the classification issues,
the rich labeled data could be more useful in the training stage. 3D object classification and pose estimation
is a jointed mission aiming at separate different posea apart in the descriptor form.
In the training stage, we prepare 2D training images generated from our module with their
class label and pose label. We fully exploit the information that lies in their labels
by using a triplet and pair-wise jointed loss function in CNN training.
Both class and pose label are in consideration in the triplet loss. The loss score
will be smaller when features from the same class and same pose is more similar
and features from different classes or different poses will lead to a much larger loss score.
This loss is also jointed with a pair wise component to make sure the loss is never be zero
and have a restriction on the model scale.
About the training and feature extraction process, it is a rough implementation by using OpenCV
and Caffe from the idea of Paul Wohlhart. The principal purpose of this API is constructing
a well labeled database from .ply models for CNN training with triplet loss and extracting features
with the constructed model for prediction or other purpose of pattern recognition, algorithms into two main Class:
**icoSphere: methods belonging to this class generates 2D images from a 3D model, together with their class and pose from camera view labels.
**descriptorExtractor: methods belonging to this class extract descriptors from 2D images which is
discriminant on category prediction and pose estimation.
@note This API need Caffe with triplet version which is designed for this module
<https://github.com/Wangyida/caffe/tree/cnn_triplet>.
*/
namespace cv
{
namespace cnn_3dobj
{
//! @addtogroup cnn_3dobj
//! @{
/** @brief Icosohedron based camera view data generator.
The class create some sphere views of camera towards a 3D object meshed from .ply files @cite hinterstoisser2008panter .
*/
/************************************ Data Generation Class ************************************/
class CV_EXPORTS_W icoSphere
{
private:
/** @brief X position of one base point on the initial Icosohedron sphere,
Y is set to be 0 as default.
*/
float X;
/** @brief Z position of one base point on the initial Icosohedron sphere.
*/
float Z;
/** @brief A threshold for the dupicated points elimination.
*/
float diff;
/** @brief Temp camera position for duplex position elimination.
*/
std::vector<cv::Point3d> CameraPos_temp;
/** @brief Make all view points having the same distance from the focal point used by the camera view.
*/
CV_WRAP void norm(float v[]);
/** @brief Add a new view point.
*/
CV_WRAP void add(float v[]);
/** @brief Generate new view points from all triangles.
*/
CV_WRAP void subdivide(float v1[], float v2[], float v3[], int depth);
public:
/** @brief Camera position on the sphere after duplicated points elimination.
*/
std::vector<cv::Point3d> CameraPos;
/** @brief Generating a sphere by mean of a iteration based points selection process.
@param radius_in Another radius used for adjusting the view distance.
@param depth_in Number of interations for increasing the points on sphere.
*/
icoSphere(float radius_in, int depth_in);
/** @brief Get the center of points on surface in .ply model.
@param cloud Point cloud used for computing the center point.
*/
CV_WRAP cv::Point3d getCenter(cv::Mat cloud);
/** @brief Get the proper camera radius from the view point to the center of model.
@param cloud Point cloud used for computing the center point.
@param center center point of the point cloud.
*/
CV_WRAP float getRadius(cv::Mat cloud, cv::Point3d center);
/** @brief Suit the position of bytes in 4 byte data structure for particular system.
*/
CV_WRAP static int swapEndian(int val);
/** @brief Create header in binary files collecting the image data and label.
@param num_item Number of items.
@param rows Rows of a single sample image.
@param cols Columns of a single sample image.
@param headerPath Path where the header will be stored.
*/
CV_WRAP static void createHeader(int num_item, int rows, int cols, const char* headerPath);
/** @brief Write binary files used for training in other open source project including Caffe.
@param filenameImg Path which including a set of images.
@param binaryPath Path which will output a binary file.
@param headerPath Path which header belongs to.
@param num_item Number of samples.
@param label_class Class label of the sample.
@param x Pose label of X.
@param y Pose label of Y.
@param z Pose label of Z.
@param isrgb Option for choice of using RGB images or not.
*/
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, int isrgb);
};
/** @brief Caffe based 3D images descriptor.
A class to extract features from an image. The so obtained descriptors can be used for classification and pose estimation goals @cite wohlhart15.
*/
/************************************ Feature Extraction Class ************************************/
class CV_EXPORTS_W descriptorExtractor
{
private:
caffe::Net<float>* convnet;
cv::Size input_geometry;
int num_channels;
bool net_set;
int net_ready;
cv::Mat mean_;
String deviceType;
int deviceId;
/** @brief Load the mean file in binaryproto format if it is needed.
@param mean_file Path of mean file which stores the mean of training images, it is usually generated by Caffe tool.
*/
void setMean(const String& mean_file);
/** @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 wrapInput(std::vector<cv::Mat>* input_channels);
/** @brief Convert the input image to the input image format of the network.
*/
void preprocess(const cv::Mat& img, std::vector<cv::Mat>* input_channels);
public:
/** @brief Set the device for feature extraction, if the GPU is used, there should be a device_id.
@param device_type CPU or GPU.
@param device_id ID of GPU.
*/
descriptorExtractor(const String& device_type, int device_id = 0);
/** @brief Get device type information for feature extraction.
*/
String getDeviceType();
/** @brief Get device ID information for feature extraction.
*/
int getDeviceId();
/** @brief Set device type information for feature extraction.
Useful to change device without the need to reload the net.
@param device_type CPU or GPU.
*/
void setDeviceType(const String& device_type);
/** @brief Set device ID information for feature extraction.
Useful to change device without the need to reload the net. Only used for GPU.
@param device_id ID of GPU.
*/
void setDeviceId(const int& device_id);
/** @brief Initiate a classification structure, the net work parameter is stored in model_file,
the network structure is stored in trained_file, you can decide whether to use mean images or not.
@param model_file Path of caffemodel which including all parameters in CNN.
@param trained_file Path of prototxt which defining the structure of CNN.
@param mean_file Path of mean file(option).
*/
void loadNet(const String& model_file, const String& trained_file, const String& mean_file = "");
/** @brief Extract features from a single image or from a vector of images.
If loadNet was not called before, this method invocation will fail.
@param inputimg Input images.
@param feature Output features.
@param feature_blob Layer which the feature is extracted from.
*/
void extract(InputArrayOfArrays inputimg, OutputArray feature, String feature_blob);
};
//! @}
}
}
#endif /* CNN_3DOBJ_HPP_ */
#endif

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb ")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
project(cnn_3dobj)
find_package(OpenCV REQUIRED)
set(SOURCES_generator demo_sphereview_data.cpp)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(sphereview_test ${SOURCES_generator})
target_link_libraries(sphereview_test opencv_core opencv_imgproc opencv_highgui opencv_cnn_3dobj opencv_xfeatures2d)
set(SOURCES_classifier demo_classify.cpp)
add_executable(classify_test ${SOURCES_classifier})
target_link_libraries(classify_test opencv_core opencv_imgproc opencv_highgui opencv_cnn_3dobj opencv_xfeatures2d)
set(SOURCES_modelanalysis demo_model_analysis.cpp)
add_executable(model_test ${SOURCES_modelanalysis})
target_link_libraries(model_test opencv_core opencv_imgproc opencv_highgui opencv_cnn_3dobj opencv_xfeatures2d)
set(SOURCES_video demo_video.cpp)
add_executable(video_test ${SOURCES_video})
target_link_libraries(video_test opencv_core opencv_imgproc opencv_highgui opencv_cnn_3dobj opencv_xfeatures2d)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,91 @@
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/01.ply -label_class=1 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/02.ply -label_class=1 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/03.ply -label_class=1 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/04.ply -label_class=1 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/05.ply -label_class=1 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/06.ply -label_class=1 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/07.ply -label_class=1 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/08.ply -label_class=1 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/01.ply -label_class=2 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/02.ply -label_class=2 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/03.ply -label_class=2 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/04.ply -label_class=2 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/05.ply -label_class=2 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/06.ply -label_class=2 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/01.ply -label_class=3 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/02.ply -label_class=3 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/03.ply -label_class=3 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/04.ply -label_class=3 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/05.ply -label_class=3 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/06.ply -label_class=3 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/01.ply -label_class=4 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/02.ply -label_class=4 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/03.ply -label_class=4 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/04.ply -label_class=4 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/05.ply -label_class=4 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/06.ply -label_class=4 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/07.ply -label_class=4 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bottle/08.ply -label_class=4 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bottle_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/01.ply -label_class=5 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/02.ply -label_class=5 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/03.ply -label_class=5 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/04.ply -label_class=5 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/05.ply -label_class=5 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/06.ply -label_class=5 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/01.ply -label_class=6 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/02.ply -label_class=6 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/03.ply -label_class=6 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/04.ply -label_class=6 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/05.ply -label_class=6 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/06.ply -label_class=6 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/07.ply -label_class=6 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/08.ply -label_class=6 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/09.ply -label_class=6 -label_item=9 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/10.ply -label_class=6 -label_item=10 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/01.ply -label_class=7 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/02.ply -label_class=7 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/03.ply -label_class=7 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/04.ply -label_class=7 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/05.ply -label_class=7 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/06.ply -label_class=7 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/07.ply -label_class=7 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/08.ply -label_class=7 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/09.ply -label_class=7 -label_item=9 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/chair/10.ply -label_class=7 -label_item=10 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/chair_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/01.ply -label_class=8 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/02.ply -label_class=8 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/03.ply -label_class=8 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/04.ply -label_class=8 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/05.ply -label_class=8 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/06.ply -label_class=8 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/07.ply -label_class=8 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/08.ply -label_class=8 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/09.ply -label_class=8 -label_item=9 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/10.ply -label_class=8 -label_item=10 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/11.ply -label_class=8 -label_item=11 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/diningtable/12.ply -label_class=8 -label_item=12 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/diningtable_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/01.ply -label_class=9 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/02.ply -label_class=9 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/03.ply -label_class=9 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/04.ply -label_class=9 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/05.ply -label_class=9 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/sofa/01.ply -label_class=10 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/sofa_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/sofa/02.ply -label_class=10 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/sofa_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/sofa/03.ply -label_class=10 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/sofa_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/sofa/04.ply -label_class=10 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/sofa_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/sofa/05.ply -label_class=10 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/sofa_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/sofa/06.ply -label_class=10 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/sofa_pascal/ -z_range=0.6
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/01.ply -label_class=11 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/02.ply -label_class=11 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/03.ply -label_class=11 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/04.ply -label_class=11 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2

@ -0,0 +1,45 @@
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/01.ply -label_class=1 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/02.ply -label_class=1 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/03.ply -label_class=1 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/04.ply -label_class=1 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/05.ply -label_class=1 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/06.ply -label_class=1 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/07.ply -label_class=1 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/08.ply -label_class=1 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/01.ply -label_class=2 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/02.ply -label_class=2 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/03.ply -label_class=2 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/04.ply -label_class=2 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/05.ply -label_class=2 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/06.ply -label_class=2 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/01.ply -label_class=3 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/02.ply -label_class=3 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/04.ply -label_class=3 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/05.ply -label_class=3 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/06.ply -label_class=3 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/01.ply -label_class=5 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/02.ply -label_class=5 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/03.ply -label_class=5 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/04.ply -label_class=5 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/05.ply -label_class=5 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/06.ply -label_class=5 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/01.ply -label_class=6 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/02.ply -label_class=6 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/03.ply -label_class=6 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/04.ply -label_class=6 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/05.ply -label_class=6 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/06.ply -label_class=6 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/07.ply -label_class=6 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/08.ply -label_class=6 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/09.ply -label_class=6 -label_item=9 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/10.ply -label_class=6 -label_item=10 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/01.ply -label_class=9 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/02.ply -label_class=9 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/03.ply -label_class=9 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/04.ply -label_class=9 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=2
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/05.ply -label_class=9 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=2

@ -0,0 +1,60 @@
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/01.ply -label_class=1 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/02.ply -label_class=1 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/03.ply -label_class=1 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/04.ply -label_class=1 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/05.ply -label_class=1 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/06.ply -label_class=1 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/07.ply -label_class=1 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/aeroplane/08.ply -label_class=1 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/aeroplane_pascal/ -semisphere=0 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/01.ply -label_class=2 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/02.ply -label_class=2 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/03.ply -label_class=2 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/04.ply -label_class=2 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/05.ply -label_class=2 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bicycle/06.ply -label_class=2 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bicycle_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/01.ply -label_class=3 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/02.ply -label_class=3 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/04.ply -label_class=3 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/05.ply -label_class=3 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/boat/06.ply -label_class=3 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/boat_pascal/ -z_range=0.6 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/01.ply -label_class=5 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/02.ply -label_class=5 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/03.ply -label_class=5 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/04.ply -label_class=5 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/05.ply -label_class=5 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/bus/06.ply -label_class=5 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/bus_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/01.ply -label_class=6 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/02.ply -label_class=6 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/03.ply -label_class=6 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/04.ply -label_class=6 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/05.ply -label_class=6 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/06.ply -label_class=6 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/07.ply -label_class=6 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/08.ply -label_class=6 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/09.ply -label_class=6 -label_item=9 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/car/10.ply -label_class=6 -label_item=10 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/car_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/01.ply -label_class=9 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/02.ply -label_class=9 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/03.ply -label_class=9 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/04.ply -label_class=9 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/motorbike/05.ply -label_class=9 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/motorbike_pascal/ -z_range=0.5 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/01.ply -label_class=11 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/02.ply -label_class=11 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/03.ply -label_class=11 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/04.ply -label_class=11 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/train/05.ply -label_class=11 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/train_pascal/ -z_range=0.2 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/01.ply -label_class=12 -label_item=1 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/02.ply -label_class=12 -label_item=2 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/03.ply -label_class=12 -label_item=3 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/04.ply -label_class=12 -label_item=4 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/05.ply -label_class=12 -label_item=5 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/06.ply -label_class=12 -label_item=6 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/07.ply -label_class=12 -label_item=7 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1
./sphereview_test -plymodel=/Users/yidawang/Documents/database/PASCAL3D+_release1.1/CAD/tvmonitor/08.ply -label_class=12 -label_item=8 -bakgrdir=/Users/yidawang/Documents/database/backgrd_pascal/tvmonitor_pascal/ -z_range=0.3 -view_region=1

@ -0,0 +1,201 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2009, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file demo_classify.cpp
* @brief Feature extraction and classification.
* @author Yida Wang
*/
#include <opencv2/cnn_3dobj.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iomanip>
using namespace cv;
using namespace std;
using namespace cv::cnn_3dobj;
/**
* @function listDir
* @brief Making all files names under a directory into a list
*/
void listDir(const char *path, std::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)
{
if (ent->d_type & DT_DIR)
{
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0 || strcmp(ent->d_name, ".DS_Store") == 0)
{
continue;
}
if (r)
{
sprintf(childpath, "%s/%s", path, ent->d_name);
listDir(childpath,files,false);
}
}
else
{
if (strcmp(ent->d_name, ".DS_Store") != 0)
files.push_back(ent->d_name);
}
}
sort(files.begin(),files.end());
};
/**
* @function featureWrite
* @brief Writing features of gallery images into binary files
*/
int featureWrite(const Mat &features, const String &fname)
{
ofstream ouF;
ouF.open(fname.c_str(), std::ofstream::binary);
if (!ouF)
{
cerr << "failed to open the file : " << fname << endl;
return 0;
}
for (int r = 0; r < features.rows; r++)
{
ouF.write(reinterpret_cast<const char*>(features.ptr(r)), features.cols*features.elemSize());
}
ouF.close();
return 1;
}
/**
* @function main
*/
int main(int argc, char** argv)
{
const String keys = "{help | | This sample will extract features from reference images and target image for classification. You can add a mean_file if there little variance in data such as human faces, otherwise it is not so useful}"
"{src_dir | ../data/images_all/ | Source direction of the images ready for being used for extract feature as gallery.}"
"{caffemodel | ../../testdata/cv/3d_triplet_iter_30000.caffemodel | caffe model for feature exrtaction.}"
"{network_forIMG | ../../testdata/cv/3d_triplet_testIMG.prototxt | Network definition file used for extracting feature from a single image and making a classification}"
"{mean_file | no | The mean file generated by Caffe from all gallery images, this could be used for mean value substraction from all images. If you want to use the mean file, you can set this as ../data/images_mean/triplet_mean.binaryproto.}"
"{target_img | ../data/images_all/4_78.png | Path of image waiting to be classified.}"
"{feature_blob | feat | Name of layer which will represent as the feature, in this network, ip1 or feat is well.}"
"{num_candidate | 15 | Number of candidates in gallery as the prediction result.}"
"{device | CPU | Device type: CPU or GPU}"
"{dev_id | 0 | Device id}"
"{gallery_out | 0 | Option on output binary features on gallery images}";
/* get parameters from comand line */
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Feature extraction and classification");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String src_dir = parser.get<String>("src_dir");
String caffemodel = parser.get<String>("caffemodel");
String network_forIMG = parser.get<String>("network_forIMG");
String mean_file = parser.get<String>("mean_file");
String target_img = parser.get<String>("target_img");
String feature_blob = parser.get<String>("feature_blob");
int num_candidate = parser.get<int>("num_candidate");
String device = parser.get<String>("device");
int dev_id = parser.get<int>("dev_id");
int gallery_out = parser.get<int>("gallery_out");
/* Initialize a net work with Device */
cv::cnn_3dobj::descriptorExtractor descriptor(device);
std::cout << "Using" << descriptor.getDeviceType() << std::endl;
/* Load net with the caffe trained net work parameter and structure */
if (strcmp(mean_file.c_str(), "no") == 0)
descriptor.loadNet(network_forIMG, caffemodel);
else
descriptor.loadNet(network_forIMG, caffemodel, mean_file);
std::vector<String> name_gallery;
/* List the file names under a given path */
listDir(src_dir.c_str(), name_gallery, false);
if (gallery_out)
{
ofstream namelist_out("gallelist.txt");
/* Writing name of the reference images. */
for (unsigned int i = 0; i < name_gallery.size(); i++)
namelist_out << name_gallery.at(i) << endl;
}
for (unsigned int i = 0; i < name_gallery.size(); i++)
{
name_gallery[i] = src_dir + name_gallery[i];
}
std::vector<cv::Mat> img_gallery;
cv::Mat feature_reference;
for (unsigned int i = 0; i < name_gallery.size(); i++)
{
img_gallery.push_back(cv::imread(name_gallery[i]));
}
/* Extract feature from a set of images */
descriptor.extract(img_gallery, feature_reference, feature_blob);
if (gallery_out)
{
std::cout << std::endl << "---------- Features of gallery images ----------" << std::endl;
/* Print features of the reference images. */
for (unsigned int i = 0; i < feature_reference.rows; i++)
std::cout << feature_reference.row(i) << endl;
std::cout << std::endl << "---------- Saving features of gallery images into feature.bin ----------" << std::endl;
featureWrite(feature_reference, "feature.bin");
}
else
{
std::cout << std::endl << "---------- Prediction for " << target_img << " ----------" << std::endl;
cv::Mat img = cv::imread(target_img);
std::cout << std::endl << "---------- Features of gallery images ----------" << std::endl;
std::vector<std::pair<String, float> > prediction;
/* Print features of the reference images. */
for (unsigned int i = 0; i < feature_reference.rows; i++)
std::cout << feature_reference.row(i) << endl;
cv::Mat feature_test;
descriptor.extract(img, feature_test, feature_blob);
/* Initialize a matcher which using L2 distance. */
cv::BFMatcher matcher(NORM_L2);
std::vector<std::vector<cv::DMatch> > matches;
/* Have a KNN match on the target and reference images. */
matcher.knnMatch(feature_test, feature_reference, matches, num_candidate);
/* Print feature of the target image waiting to be classified. */
std::cout << std::endl << "---------- Features of target image: " << target_img << "----------" << endl << feature_test << std::endl;
/* Print the top N prediction. */
std::cout << std::endl << "---------- Prediction result(Distance - File Name in Gallery) ----------" << std::endl;
for (size_t i = 0; i < matches[0].size(); ++i)
{
std::cout << i << " - " << std::fixed << std::setprecision(2) << name_gallery[matches[0][i].trainIdx] << " - \"" << matches[0][i].distance << "\"" << std::endl;
}
}
return 0;
}

@ -0,0 +1,155 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2009, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file sphereview_3dobj_demo.cpp
* @brief Generating training data for CNN with triplet loss.
* @author Yida Wang
*/
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/cnn_3dobj.hpp"
using namespace cv;
using namespace cv::cnn_3dobj;
int main(int argc, char** argv)
{
const String keys = "{help | | this demo will have an analysis on the trained model, it will print information about whether the model is suit for set different classes apart and also discriminant on object pose at the same time.}"
"{caffemodel | ../../testdata/cv/3d_triplet_iter_30000.caffemodel | caffe model for feature exrtaction.}"
"{network_forIMG | ../../testdata/cv/3d_triplet_testIMG.prototxt | Network definition file used for extracting feature from a single image and making a classification}"
"{mean_file | no | The mean file generated by Caffe from all gallery images, this could be used for mean value substraction from all images. If you want to use the mean file, you can set this as ../data/images_mean/triplet_mean.binaryproto.}"
"{target_img | ../data/images_all/4_78.png | Path of image in reference.}"
"{ref_img1 | ../data/images_all/4_79.png | Path of closest image.}"
"{ref_img2 | ../data/images_all/4_87.png | Path of less closer image in the same class with reference image.}"
"{ref_img3 | ../data/images_all/3_78.png | Path of image with the same pose in another class.}"
"{feature_blob | feat | Name of layer which will represent as the feature, in this network, ip1 or feat is well.}"
"{device | CPU | device}"
"{dev_id | 0 | dev_id}";
/* Get parameters from comand line. */
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Demo for object data classification and pose estimation");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String caffemodel = parser.get<String>("caffemodel");
String network_forIMG = parser.get<String>("network_forIMG");
String mean_file = parser.get<String>("mean_file");
String target_img = parser.get<String>("target_img");
String ref_img1 = parser.get<String>("ref_img1");
String ref_img2 = parser.get<String>("ref_img2");
String ref_img3 = parser.get<String>("ref_img3");
String feature_blob = parser.get<String>("feature_blob");
String device = parser.get<String>("device");
int dev_id = parser.get<int>("dev_id");
std::vector<String> ref_img;
/* Sample which is most closest in pose to reference image
*and also the same class.
*/
ref_img.push_back(ref_img1);
/* Sample which is less closest in pose to reference image
*and also the same class.
*/
ref_img.push_back(ref_img2);
/* Sample which is very close in pose to reference image
*but not the same class.
*/
ref_img.push_back(ref_img3);
/* Initialize a net work with Device. */
cv::cnn_3dobj::descriptorExtractor descriptor(device, dev_id);
/* Load net with the caffe trained net work parameter and structure. */
if (strcmp(mean_file.c_str(), "no") == 0)
descriptor.loadNet(network_forIMG, caffemodel);
else
descriptor.loadNet(network_forIMG, caffemodel, mean_file);
cv::Mat img_base = cv::imread(target_img, -1);
if (img_base.empty())
{
printf("could not read reference image %s\n, make sure the path of images are set properly.", target_img.c_str());
}
std::vector<cv::Mat> img;
for (unsigned int i = 0; i < ref_img.size(); i++)
{
img.push_back(cv::imread(ref_img[i], -1));
if (img[i].empty()) {
printf("could not read reference image %s\n, make sure the path of images are set properly.", ref_img[i].c_str());
}
}
cv::Mat feature_test;
descriptor.extract(img_base, feature_test, feature_blob);
if (feature_test.empty()) {
printf("could not extract feature from test image which is read into cv::Mat.");
}
cv::Mat feature_reference;
descriptor.extract(img, feature_reference, feature_blob);
if (feature_reference.empty()) {
printf("could not extract feature from reference images which is already stored in vector<cv::Mat>.");
}
std::vector<float> matches;
for (int i = 0; i < feature_reference.rows; i++)
{
cv::Mat distance = feature_test-feature_reference.row(i);
matches.push_back(cv::norm(distance));
}
bool pose_pass = false;
bool class_pass = false;
/* Have comparations on the distance between reference image and 3 other images
*distance between closest sample and reference image should be smallest and
*distance between sample in another class and reference image should be largest.
*/
if (matches[0] < matches[1] && matches[0] < matches[2])
pose_pass = true;
if (matches[1] < matches[2])
class_pass = true;
if (!pose_pass)
{
printf("\n =========== Model %s ========== \nIs not trained properly that the similar pose could not be tell from a cluster of features.\n", caffemodel.c_str());
}
else if (!class_pass)
{
printf("\n =========== Model %s ========== \nIs not trained properly that feature from the same class is not discriminant from the one of another class with similar pose.\n", caffemodel.c_str());
}
else
{
printf("\n =========== Model %s ========== \nSuits for setting different classes apart and also discriminant on object pose at the same time.\n", caffemodel.c_str());
}
return 0;
}

@ -0,0 +1,333 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2009, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file demo_sphereview_data.cpp
* @brief Generating training data for CNN with triplet loss.
* @author Yida Wang
*/
#include <opencv2/cnn_3dobj.hpp>
#include <opencv2/viz/vizcore.hpp>
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace cv;
using namespace std;
using namespace cv::cnn_3dobj;
/**
* @function listDir
* @brief Making all files names under a directory into a list
*/
void listDir(const char *path, std::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)
{
if (ent->d_type & DT_DIR)
{
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0 || strcmp(ent->d_name, ".DS_Store") == 0)
{
continue;
}
if (r)
{
sprintf(childpath, "%s/%s", path, ent->d_name);
listDir(childpath,files,false);
}
}
else
{
if (strcmp(ent->d_name, ".DS_Store") != 0)
files.push_back(ent->d_name);
}
}
sort(files.begin(),files.end());
};
int main(int argc, char *argv[])
{
const String keys = "{help | | demo :$ ./sphereview_test -ite_depth=2 -plymodel=../data/3Dmodel/ape.ply -imagedir=../data/images_all/ -labeldir=../data/label_all.txt -num_class=6 -label_class=0, then press 'q' to run the demo for images generation when you see the gray background and a coordinate.}"
"{ite_depth | 3 | Iteration of sphere generation.}"
"{plymodel | ../data/3Dmodel/ape.ply | Path of the '.ply' file for image rendering. }"
"{imagedir | ../data/images_all/ | Path of the generated images for one particular .ply model. }"
"{labeldir | ../data/label_all.txt | Path of the generated images for one particular .ply model. }"
"{bakgrdir | | Path of the backgroud images sets. }"
"{cam_head_x | 0 | Head of the camera. }"
"{cam_head_y | 0 | Head of the camera. }"
"{cam_head_z | -1 | Head of the camera. }"
"{semisphere | 1 | Camera only has positions on half of the whole sphere. }"
"{z_range | 0.6 | Maximum camera position on z axis. }"
"{center_gen | 0 | Find center from all points. }"
"{image_size | 128 | Size of captured images. }"
"{label_class | | Class label of current .ply model. }"
"{label_item | | Item label of current .ply model. }"
"{rgb_use | 0 | Use RGB image or grayscale. }"
"{num_class | 6 | Total number of classes of models. }"
"{binary_out | 0 | Produce binaryfiles for images and label. }"
"{view_region | 0 | Take a special view of front or back angle}";
/* Get parameters from comand line. */
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Generating training data for CNN with triplet loss");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
int ite_depth = parser.get<int>("ite_depth");
String plymodel = parser.get<String>("plymodel");
String imagedir = parser.get<String>("imagedir");
string labeldir = parser.get<String>("labeldir");
String bakgrdir = parser.get<string>("bakgrdir");
int label_class = parser.get<int>("label_class");
int label_item = parser.get<int>("label_item");
float cam_head_x = parser.get<float>("cam_head_x");
float cam_head_y = parser.get<float>("cam_head_y");
float cam_head_z = parser.get<float>("cam_head_z");
int semisphere = parser.get<int>("semisphere");
float z_range = parser.get<float>("z_range");
int center_gen = parser.get<int>("center_gen");
int image_size = parser.get<int>("image_size");
int rgb_use = parser.get<int>("rgb_use");
int num_class = parser.get<int>("num_class");
int binary_out = parser.get<int>("binary_out");
int view_region = parser.get<int>("view_region");
double obj_dist, bg_dist, y_range;
if (view_region == 1 || view_region == 2)
{
/* Set for TV */
if (label_class == 12)
obj_dist = 340;
else
obj_dist = 250;
ite_depth = ite_depth + 1;
bg_dist = 700;
y_range = 0.85;
}
else if (view_region == 0)
{
obj_dist = 370;
bg_dist = 400;
}
if (label_class == 5 | label_class == 10 | label_class == 11 | label_class == 12)
ite_depth = ite_depth + 1;
cv::cnn_3dobj::icoSphere ViewSphere(10,ite_depth);
std::vector<cv::Point3d> campos;
std::vector<cv::Point3d> campos_temp = ViewSphere.CameraPos;
/* Regular objects on the ground using a semisphere view system */
if (semisphere == 1)
{
if (view_region == 1)
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z >= 0 && campos_temp.at(pose).z < z_range && campos_temp.at(pose).y < -y_range)
campos.push_back(campos_temp.at(pose));
}
}
else if (view_region == 2)
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z >= 0 && campos_temp.at(pose).z < z_range && campos_temp.at(pose).y > y_range)
campos.push_back(campos_temp.at(pose));
}
}
else
{
/* Set for sofa */
if (label_class == 10)
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z >= 0 && campos_temp.at(pose).z < z_range && campos_temp.at(pose).y < -0.4)
campos.push_back(campos_temp.at(pose));
}
}
else
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z >= 0 && campos_temp.at(pose).z < z_range)
campos.push_back(campos_temp.at(pose));
}
}
}
}
/* Special object such as plane using a full space of view sphere */
else
{
if (view_region == 1)
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z < 0.2 && campos_temp.at(pose).z > -0.2 && campos_temp.at(pose).y < -y_range)
campos.push_back(campos_temp.at(pose));
}
}
else if (view_region == 2)
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z < 0.2 && campos_temp.at(pose).z > -0.2 && campos_temp.at(pose).y > y_range)
campos.push_back(campos_temp.at(pose));
}
}
else
{
for (int pose = 0; pose < static_cast<int>(campos_temp.size()); pose++)
{
if (campos_temp.at(pose).z < 0.2 && campos_temp.at(pose).z > -0.6)
campos.push_back(campos_temp.at(pose));
}
}
}
std::fstream imglabel;
char* p=(char*)labeldir.data();
imglabel.open(p, fstream::app|fstream::out);
bool camera_pov = true;
/* Create a window using viz. */
viz::Viz3d myWindow("Coordinate Frame");
/* Set window size. */
myWindow.setWindowSize(Size(image_size,image_size));
/* Set background color. */
myWindow.setBackgroundColor(viz::Color::gray());
myWindow.spin();
/* Create a Mesh widget, loading .ply models. */
viz::Mesh objmesh = viz::Mesh::load(plymodel);
/* Get the center of the generated mesh widget, cause some .ply files, this could be ignored if you are using PASCAL database*/
Point3d cam_focal_point;
if (center_gen)
cam_focal_point = ViewSphere.getCenter(objmesh.cloud);
else
cam_focal_point = Point3d(0,0,0);
const char* headerPath = "../data/header_for_";
const char* binaryPath = "../data/binary_";
if (binary_out)
{
ViewSphere.createHeader(static_cast<int>(campos.size()), image_size, image_size, headerPath);
}
float radius = ViewSphere.getRadius(objmesh.cloud, cam_focal_point);
objmesh.cloud = objmesh.cloud/radius*100;
cam_focal_point = cam_focal_point/radius*100;
Point3d cam_y_dir;
cam_y_dir.x = cam_head_x;
cam_y_dir.y = cam_head_y;
cam_y_dir.z = cam_head_z;
char* temp = new char;
char* bgname = new char;
std::vector<String> name_bkg;
if (bakgrdir.size() != 0)
{
/* List the file names under a given path */
listDir(bakgrdir.c_str(), name_bkg, false);
for (unsigned int i = 0; i < name_bkg.size(); i++)
{
name_bkg.at(i) = bakgrdir + name_bkg.at(i);
}
}
/* Images will be saved as .png files. */
int cnt_img;
srand((int)time(0));
do
{
cnt_img = 0;
for(int pose = 0; pose < static_cast<int>(campos.size()); pose++){
/* Add light. */
// double alpha1 = rand()%(314/2)/100;
// double alpha2 = rand()%(314*2)/100;
// printf("%f %f %f/n", ceil(10000*sqrt(1 - sin(alpha1)*sin(alpha1))*sin(alpha2)), 10000*sqrt(1 - sin(alpha1)*sin(alpha1))*cos(alpha2), sin(alpha1)*10000);
// myWindow.addLight(Vec3d(10000*sqrt(1 - sin(alpha1)*sin(alpha1))*sin(alpha2),10000*sqrt(1 - sin(alpha1)*sin(alpha1))*cos(alpha2),sin(alpha1)*10000), Vec3d(0,0,0), viz::Color::white(), viz::Color::white(), viz::Color::black(), viz::Color::white());
int label_x, label_y, label_z;
label_x = static_cast<int>(campos.at(pose).x*100);
label_y = static_cast<int>(campos.at(pose).y*100);
label_z = static_cast<int>(campos.at(pose).z*100);
sprintf (temp,"%02i_%02i_%04i_%04i_%04i_%02i", label_class, label_item, label_x, label_y, label_z, static_cast<int>(obj_dist/100));
String filename = temp;
filename += ".png";
imglabel << filename << ' ' << label_class << endl;
filename = imagedir + filename;
/* Get the pose of the camera using makeCameraPoses. */
if (view_region != 0)
{
cam_focal_point.x = cam_focal_point.y - label_x/5;
}
Affine3f cam_pose = viz::makeCameraPose(campos.at(pose)*obj_dist+cam_focal_point, cam_focal_point, cam_y_dir*obj_dist+cam_focal_point);
/* Get the transformation matrix from camera coordinate system to global. */
Affine3f transform = viz::makeTransformToGlobal(Vec3f(1.0f,0.0f,0.0f), Vec3f(0.0f,1.0f,0.0f), Vec3f(0.0f,0.0f,1.0f), campos.at(pose));
viz::WMesh mesh_widget(objmesh);
/* Pose of the widget in camera frame. */
Affine3f cloud_pose = Affine3f().translate(Vec3f(1.0f,1.0f,1.0f));
/* Pose of the widget in global frame. */
Affine3f cloud_pose_global = transform * cloud_pose;
/* Visualize camera frame. */
if (!camera_pov)
{
viz::WCameraPosition cpw(1); // Coordinate axes
viz::WCameraPosition cpw_frustum(Vec2f(0.5, 0.5)); // Camera frustum
myWindow.showWidget("CPW", cpw, cam_pose);
myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
}
/* Visualize widget. */
if (bakgrdir.size() != 0)
{
cv::Mat img_bg = cv::imread(name_bkg.at(rand()%name_bkg.size()));
/* Back ground images has a distance of 2 times of radius of camera view distance */
cv::viz::WImage3D background_widget(img_bg, Size2d(image_size*4.2, image_size*4.2), Vec3d(-campos.at(pose)*bg_dist+cam_focal_point), Vec3d(campos.at(pose)*bg_dist-cam_focal_point), Vec3d(0,0,-1)*bg_dist+Vec3d(0,2*cam_focal_point.y,0));
myWindow.showWidget("bgwidget", background_widget, cloud_pose_global);
}
// mesh_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("targetwidget", mesh_widget, cloud_pose_global);
/* Set the viewer pose to that of camera. */
if (camera_pov)
myWindow.setViewerPose(cam_pose);
/* Save screen shot as images. */
myWindow.saveScreenshot(filename);
if (binary_out)
{
/* Write images into binary files for further using in CNN training. */
ViewSphere.writeBinaryfile(filename, binaryPath, headerPath,static_cast<int>(campos.size())*num_class, label_class, static_cast<int>(campos.at(pose).x*100), static_cast<int>(campos.at(pose).y*100), static_cast<int>(campos.at(pose).z*100), rgb_use);
}
cnt_img++;
}
} while (cnt_img != campos.size());
imglabel.close();
return 1;
};

@ -0,0 +1,391 @@
#include <opencv2/viz/vizcore.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <iostream>
#include <fstream>
#include <opencv2/cnn_3dobj.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iomanip>
using namespace cv;
using namespace std;
using namespace cv::cnn_3dobj;
/**
* @function listDir
* @brief Making all files names under a directory into a list
*/
void listDir(const char *path, std::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)
{
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);
listDir(childpath,files,false);
}
}
else
{
files.push_back(ent->d_name);
}
}
sort(files.begin(),files.end());
};
/**
* @function cvcloud_load
* @brief load bunny.ply
*/
Mat cvcloud_load(Mat feature_reference)
{
Mat cloud(1, feature_reference.rows, CV_32FC3);
Point3f* data = cloud.ptr<cv::Point3f>();
float dummy1, dummy2;
for(size_t i = 0; i < feature_reference.rows; ++i)
{
data[i].x = feature_reference.at<float>(i,0);
data[i].y = feature_reference.at<float>(i,1);
data[i].z = feature_reference.at<float>(i,2);
}
cloud *= 5.0f;
return cloud;
}
/**
* @function main
*/
int main(int argc, char **argv)
{
const String keys = "{help | | This sample will extract featrues from reference images and target image for classification. You can add a mean_file if there little variance in data such as human faces, otherwise it is not so useful}"
"{src_dir | ../data/images_all/ | Source direction of the images ready for being used for extract feature as gallery.}"
"{caffemodellist | ../../testdata/cv/caffemodel_list.txt | caffe model for feature exrtaction.}"
"{network_forIMG | ../../testdata/cv/3d_triplet_testIMG.prototxt | Network definition file used for extracting feature from a single image and making a classification}"
"{mean_file | no | The mean file generated by Caffe from all gallery images, this could be used for mean value substraction from all images. If you want to use the mean file, you can set this as ../data/images_mean/triplet_mean.binaryproto.}"
"{target_img1 | ../data/images_all/0_48.png | Path of image waiting to be classified.}"
"{target_img2 | ../data/images_all/1_339.png | Path of image waiting to be classified.}"
"{target_img3 | ../data/images_all/2_296.png | Path of image waiting to be classified.}"
"{target_img4 | ../data/images_all/3_466.png | Path of image waiting to be classified.}"
"{target_img5 | ../data/images_all/4_117.png | Path of image waiting to be classified.}"
"{target_img6 | ../data/images_all/5_236.png | Path of image waiting to be classified.}"
"{feature_blob | feat | Name of layer which will represent as the feature, in this network, ip1 or feat is well.}"
"{num_candidate | 4 | Number of candidates in gallery as the prediction result.}"
"{device | CPU | Device type: CPU or GPU}"
"{dev_id | 0 | Device id}";
/* get parameters from comand line */
cv::CommandLineParser parser(argc, argv, keys);
parser.about("Feature extraction and classification");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String src_dir = parser.get<String>("src_dir");
String caffemodellist = parser.get<String>("caffemodellist");
String network_forIMG = parser.get<String>("network_forIMG");
String mean_file = parser.get<String>("mean_file");
String target_img1 = parser.get<String>("target_img1");
String target_img2 = parser.get<String>("target_img2");
String target_img3 = parser.get<String>("target_img3");
String target_img4 = parser.get<String>("target_img4");
String target_img5 = parser.get<String>("target_img5");
String target_img6 = parser.get<String>("target_img6");
String feature_blob = parser.get<String>("feature_blob");
int num_candidate = parser.get<int>("num_candidate");
String device = parser.get<String>("device");
int dev_id = parser.get<int>("dev_id");
ifstream namelist_model(caffemodellist.c_str(), ios::in);
vector<String> caffemodel;
char *buf = new char[512];
int number_model = 0;
while (!namelist_model.eof())
{
namelist_model.getline(buf, 512);
caffemodel.push_back(buf);
number_model++;
}
/* List the file names under a given path */
std::vector<String> name_gallery;
listDir(src_dir.c_str(), name_gallery, false);
for (unsigned int i = 0; i < name_gallery.size(); i++)
{
name_gallery[i] = src_dir + name_gallery[i];
}
std::vector<cv::Mat> img_gallery;
cv::Mat temp_feat;
vector<cv::Mat> feature_reference;
vector<cv::Mat> feature_test1;
vector<cv::Mat> feature_test2;
vector<cv::Mat> feature_test3;
vector<cv::Mat> feature_test4;
vector<cv::Mat> feature_test5;
vector<cv::Mat> feature_test6;
cv::Mat img_test1 = cv::imread(target_img1, -1);
cv::Mat img_test2 = cv::imread(target_img2, -1);
cv::Mat img_test3 = cv::imread(target_img3, -1);
cv::Mat img_test4 = cv::imread(target_img4, -1);
cv::Mat img_test5 = cv::imread(target_img5, -1);
cv::Mat img_test6 = cv::imread(target_img6, -1);
for (int num_model = 0; num_model < number_model; ++num_model)
{
feature_reference.push_back(temp_feat);
feature_test1.push_back(temp_feat);
feature_test2.push_back(temp_feat);
feature_test3.push_back(temp_feat);
feature_test4.push_back(temp_feat);
feature_test5.push_back(temp_feat);
feature_test6.push_back(temp_feat);
}
for (unsigned int i = 0; i < name_gallery.size(); i++)
{
img_gallery.push_back(cv::imread(name_gallery[i], -1));
}
/* Initialize a net work with Device */
cv::cnn_3dobj::descriptorExtractor descriptor(device);
std::cout << "Using" << descriptor.getDeviceType() << std::endl;
/* Load net with the caffe trained net work parameter and structure */
for (int num_model = 0; num_model < number_model; ++num_model)
{
if (strcmp(mean_file.c_str(), "no") == 0)
descriptor.loadNet(network_forIMG, caffemodel[num_model]);
else
descriptor.loadNet(network_forIMG, caffemodel[num_model], mean_file);
/* Part1: Extract feature from a set of images and a single image*/
descriptor.extract(img_gallery, feature_reference[num_model], feature_blob);
descriptor.extract(img_test1, feature_test1[num_model], feature_blob);
descriptor.extract(img_test2, feature_test2[num_model], feature_blob);
descriptor.extract(img_test3, feature_test3[num_model], feature_blob);
descriptor.extract(img_test4, feature_test4[num_model], feature_blob);
descriptor.extract(img_test5, feature_test5[num_model], feature_blob);
descriptor.extract(img_test6, feature_test6[num_model], feature_blob);
}
/* Initialize a matcher which using L2 distance. */
cv::BFMatcher matcher(NORM_L2);
vector<vector<vector<cv::DMatch> > > matches1;
vector<vector<vector<cv::DMatch> > > matches2;
vector<vector<vector<cv::DMatch> > > matches3;
vector<vector<vector<cv::DMatch> > > matches4;
vector<vector<vector<cv::DMatch> > > matches5;
vector<vector<vector<cv::DMatch> > > matches6;
vector<vector<cv::DMatch> > matches_temp;
for (int num_model = 0; num_model < number_model; ++num_model)
{
matches1.push_back(matches_temp);
matches2.push_back(matches_temp);
matches3.push_back(matches_temp);
matches4.push_back(matches_temp);
matches5.push_back(matches_temp);
matches6.push_back(matches_temp);
}
/* Have a KNN match on the target and reference images. */
for (int num_model = 0; num_model < number_model; ++num_model)
{
matcher.knnMatch(feature_test1[num_model], feature_reference[num_model], matches1[num_model], num_candidate+1);
matcher.knnMatch(feature_test2[num_model], feature_reference[num_model], matches2[num_model], num_candidate+1);
matcher.knnMatch(feature_test3[num_model], feature_reference[num_model], matches3[num_model], num_candidate+1);
matcher.knnMatch(feature_test4[num_model], feature_reference[num_model], matches4[num_model], num_candidate+1);
matcher.knnMatch(feature_test5[num_model], feature_reference[num_model], matches5[num_model], num_candidate+1);
matcher.knnMatch(feature_test6[num_model], feature_reference[num_model], matches6[num_model], num_candidate+1);
}
vector<Mat> img_merge;
/* Part2: Start to have a show */
bool camera_pov = true;
viz::Viz3d myWindow0("Instruction");
viz::Viz3d myWindow1("Point Cloud");
viz::Viz3d myWindow2("Prediction sample");
/* Set window size as 1024*1024, we use this scale as default. */
myWindow0.setWindowSize(Size(1300,100));
myWindow0.setWindowPosition(Point(0,800));
myWindow1.setWindowSize(Size(700,600));
myWindow1.setWindowPosition(Point(600,0));
myWindow2.setWindowSize(Size(600,600));
myWindow2.setWindowPosition(Point(-20,0));
/* Pose of the widget in camera frame */
Affine3f cloud_pose = Affine3f().translate(Vec3f(1.0f,1.0f,1.0f));
Point3d campos(1,0,0);
/* Get the transformation matrix from camera coordinate system to global. */
Affine3f transform = viz::makeTransformToGlobal(Vec3f(1.0f,0.0f,0.0f), Vec3f(0.0f,1.0f,0.0f), Vec3f(0.0f,0.0f,1.0f), campos);
/* Pose of the widget in global frame */
Affine3f cloud_pose_global = transform * cloud_pose;
/* Set background color. */
myWindow0.setBackgroundColor(viz::Color::white());
myWindow1.setBackgroundColor(viz::Color::white());
myWindow2.setBackgroundColor(viz::Color::white());
Point3d cam_y_dir(0.0f,0.0f,1.0f);
cv::cnn_3dobj::icoSphere ViewSphere(1,0);
Mat bunny_cloud;
Point3d cam_focal_point;
float radius;
float translation_phase = 0.0;
int count_pre, num_rotate, max_rotate;
String titlename, Hint, Pred("prediction: ");
vector<viz::WImageOverlay> imagepredict;
String widgename[24] = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24"};
vector<Mat> slide;
slide.push_back(imread("1.png"));
slide.push_back(imread("2.png"));
slide.push_back(imread("3.png"));
slide.push_back(imread("4.png"));
slide.push_back(imread("5.png"));
slide.push_back(imread("6.png"));
slide.push_back(imread("7.png"));
slide.push_back(imread("8.png"));
slide.push_back(imread("9.png"));
slide.push_back(imread("10.png"));
/// Create a window
viz::Viz3d myWindowS("Slide Show");
myWindowS.setWindowSize(Size(1300,700));
myWindowS.setWindowPosition(Point(0,0));
myWindowS.setBackgroundColor(viz::Color::white());
for (int i = 0; i < slide.size(); ++i)
{
/// Create a triangle widget
viz::WImageOverlay slide1(slide[i],Rect(0, 0, 1300, 700));
/// Show widget in the visualizer window
num_rotate = 0;
if (i == 0)
max_rotate = 2000;
else
max_rotate = 230;
while (num_rotate != max_rotate)
{
myWindowS.showWidget("Slide1", slide1);
/// Start event loop
myWindowS.spinOnce(1, true);
num_rotate++;
}
}
for (int num_model = 0; num_model < number_model; ++num_model)
{
if (num_model == 0)
Hint = "Start training.";
else if (num_model == 28)
Hint = "Different Classes Are Clustered.";
else if(num_model == 40)
Hint = "Poses Are Set apart.";
else if(num_model == 42)
Hint = "Finished. Model could: tell both classes and poses.";
titlename = caffemodel[num_model];
titlename = "Prediction Result of Model Trained on Iteration " + titlename.substr(34, titlename.length() - 44);
viz::WText title(titlename, Point(100, 50), 30, viz::Color::black());
viz::WText hint(Hint, Point(400, 20), 25, viz::Color::black());
viz::WImageOverlay image3d1(img_test1, Rect(20, 40, img_test4.rows, img_test4.cols));
viz::WText arrow1(Pred, Point(90,60), 15, viz::Color::red());
viz::WImageOverlay image3d2(img_test2, Rect(20, 40+75, img_test4.rows, img_test4.cols));
viz::WText arrow2(Pred, Point(90,60+75), 15, viz::Color::green());
viz::WImageOverlay image3d3(img_test3, Rect(20, 40+75*2, img_test4.rows, img_test4.cols));
viz::WText arrow3(Pred, Point(90,60+75*2), 15, viz::Color::purple());
viz::WImageOverlay image3d4(img_test4, Rect(20, 40+75*3, img_test4.rows, img_test4.cols));
viz::WText arrow4(Pred, Point(90,60+75*3), 15, viz::Color::blue());
viz::WImageOverlay image3d5(img_test5, Rect(20, 40+75*4, img_test4.rows, img_test4.cols));
viz::WText arrow5(Pred, Point(90,60+75*4), 15, viz::Color::yellow());
viz::WImageOverlay image3d6(img_test6, Rect(20, 40+75*5, img_test4.rows, img_test4.cols));
viz::WText arrow6(Pred, Point(90,60+75*5), 15, viz::Color::orange());
viz::WText text_target(String("Query Image"), Point2d(20,530), 20, viz::Color::purple());
viz::WText text_pred(String("Predicted Images using 4 NN"), Point2d(80+110,530), 20, viz::Color::purple());
viz::WText text3d1(String("1st"), Point2d(80 + 110,500), 20, viz::Color::orange());
viz::WText text3d2(String("2nd"), Point2d(80 + 2*110,500), 20, viz::Color::orange());
viz::WText text3d3(String("3rd"), Point2d(80 + 3*110,500), 20, viz::Color::orange());
viz::WText text3d4(String("4th"), Point2d(80 + 4*110,500), 20, viz::Color::orange());
viz::WText classname1(String("ape: red"), Point2d(20,10), 11, viz::Color::red());
viz::WText classname2(String("ant: green"), Point2d(120,10), 11, viz::Color::green());
viz::WText classname3(String("cow: purple"), Point2d(220,10), 11, viz::Color::purple());
viz::WText classname4(String("plane: blue"), Point2d(320,10), 11, viz::Color::blue());
viz::WText classname5(String("bunny: yellow"), Point2d(420,10), 11, viz::Color::yellow());
viz::WText classname6(String("horse: orange"), Point2d(500,10), 11, viz::Color::orange());
myWindow0.showWidget("title", title, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow0.showWidget("hint", hint, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("image3d1", image3d1, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("image3d2", image3d2, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("image3d3", image3d3, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("image3d4", image3d4, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("image3d5", image3d5, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("image3d6", image3d6, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("arrow1", arrow1, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("arrow2", arrow2, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("arrow3", arrow3, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("arrow4", arrow4, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("arrow5", arrow5, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("arrow6", arrow6, Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
myWindow2.showWidget("text_target", text_target, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("text_pred", text_pred, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("text3d1", text3d1, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("text3d2", text3d2, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("text3d3", text3d3, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("text3d4", text3d4, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("classname1", classname1, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("classname2", classname2, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("classname3", classname3, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("classname4", classname4, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("classname5", classname5, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
myWindow2.showWidget("classname6", classname6, Affine3f().translate(Vec3f(0.0f,0.0f,0.0f)));
bunny_cloud = cvcloud_load(feature_reference[num_model]);
cam_focal_point = ViewSphere.getCenter(bunny_cloud);
radius = ViewSphere.getRadius(bunny_cloud, cam_focal_point);
viz::WCloud cloud_widget1(bunny_cloud.colRange(Range(0,641)), viz::Color::red());
viz::WCloud cloud_widget2(bunny_cloud.colRange(Range(642,642*2-1)), viz::Color::green());
viz::WCloud cloud_widget3(bunny_cloud.colRange(Range(642*2,642*3-1)), viz::Color::purple());
viz::WCloud cloud_widget4(bunny_cloud.colRange(Range(642*3,642*4-1)), viz::Color::blue());
viz::WCloud cloud_widget5(bunny_cloud.colRange(Range(642*4,642*5-1)), viz::Color::yellow());
viz::WCloud cloud_widget6(bunny_cloud.colRange(Range(642*5,642*6-1)), viz::Color::orange());
myWindow1.showWidget("obj1", cloud_widget1, cloud_pose_global);
myWindow1.setRenderingProperty("obj1",0,3);
myWindow1.showWidget("obj2", cloud_widget2, cloud_pose_global);
myWindow1.setRenderingProperty("obj2",0,3);
myWindow1.showWidget("obj3", cloud_widget3, cloud_pose_global);
myWindow1.setRenderingProperty("obj3",0,3);
myWindow1.showWidget("obj4", cloud_widget4, cloud_pose_global);
myWindow1.setRenderingProperty("obj4",0,3);
myWindow1.showWidget("obj5", cloud_widget5, cloud_pose_global);
myWindow1.setRenderingProperty("obj5",0,3);
myWindow1.showWidget("obj6", cloud_widget6, cloud_pose_global);
myWindow1.setRenderingProperty("obj6",0,3);
count_pre = 0;
for (int j = 1; j < num_candidate+1; ++j)
{
myWindow2.showWidget(widgename[count_pre], viz::WImageOverlay(img_gallery[matches1[num_model][0][j].trainIdx], Rect(80+110*j, 40+75*0, img_test4.rows, img_test4.cols)), Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
count_pre++;
myWindow2.showWidget(widgename[count_pre], viz::WImageOverlay(img_gallery[matches2[num_model][0][j].trainIdx], Rect(80+110*j, 40+75*1, img_test4.rows, img_test4.cols)), Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
count_pre++;
myWindow2.showWidget(widgename[count_pre], viz::WImageOverlay(img_gallery[matches3[num_model][0][j].trainIdx], Rect(80+110*j, 40+75*2, img_test4.rows, img_test4.cols)), Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
count_pre++;
myWindow2.showWidget(widgename[count_pre], viz::WImageOverlay(img_gallery[matches4[num_model][0][j].trainIdx], Rect(80+110*j, 40+75*3, img_test4.rows, img_test4.cols)), Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
count_pre++;
myWindow2.showWidget(widgename[count_pre], viz::WImageOverlay(img_gallery[matches5[num_model][0][j].trainIdx], Rect(80+110*j, 40+75*4, img_test4.rows, img_test4.cols)), Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
count_pre++;
myWindow2.showWidget(widgename[count_pre], viz::WImageOverlay(img_gallery[matches6[num_model][0][j].trainIdx], Rect(80+110*j, 40+75*5, img_test4.rows, img_test4.cols)), Affine3f().translate(Vec3f(1.0f,1.0f,1.0f)));
count_pre++;
}
num_rotate = 0;
max_rotate = 15;
if (num_model == number_model-1)
max_rotate = 30000;
while (num_rotate != max_rotate)
{
translation_phase += CV_PI * 0.01f;
campos.x = sin(translation_phase);
campos.y = cos(translation_phase);
campos.z = 0;
/* Get the pose of the camera using makeCameraPoses. */
Affine3f cam_pose = viz::makeCameraPose(campos*radius*3.5+cam_focal_point, cam_focal_point, cam_y_dir*radius*3.5+cam_focal_point);
myWindow1.setViewerPose(cam_pose);
myWindow1.spinOnce(1, true);
myWindow2.spinOnce(1, true);
myWindow0.spinOnce(1, true);
num_rotate++;
}
myWindow0.removeAllWidgets();
myWindow1.removeAllWidgets();
myWindow2.removeAllWidgets();
}
return 0;
}

@ -0,0 +1 @@
./classify_test --src_dir=/Users/yidawang/Downloads/PASCAL3D+_release1.1/ImageCollection/ --network_forIMG=/Users/yidawang/Documents/buildboat/caffe/examples/triplet/pascal_triplet.prototxt --caffemodel=/Users/yidawang/Documents/buildboat/caffe/examples/triplet/pascal_triplet_iter_10000.caffemodel --gallery_out=1

@ -0,0 +1,259 @@
#include "precomp.hpp"
using namespace caffe;
namespace cv
{
namespace cnn_3dobj
{
descriptorExtractor::descriptorExtractor(const String& device_type, int device_id)
{
net_ready = 0;
if (strcmp(device_type.c_str(), "CPU") == 0 || strcmp(device_type.c_str(), "GPU") == 0)
{
if (strcmp(device_type.c_str(), "CPU") == 0)
{
caffe::Caffe::set_mode(caffe::Caffe::CPU);
deviceType = "CPU";
std::cout << "Using CPU" << std::endl;
}
else
{
caffe::Caffe::set_mode(caffe::Caffe::GPU);
caffe::Caffe::SetDevice(device_id);
deviceType = "GPU";
std::cout << "Using GPU" << std::endl;
std::cout << "Using Device_id=" << device_id << std::endl;
}
net_set = true;
}
else
{
std::cout << "Error: Device name must be 'GPU' together with an device number or 'CPU'." << std::endl;
net_set = false;
}
};
String descriptorExtractor::getDeviceType()
{
String device_info_out;
device_info_out = deviceType;
return device_info_out;
};
int descriptorExtractor::getDeviceId()
{
int device_info_out;
device_info_out = deviceId;
return device_info_out;
};
void descriptorExtractor::setDeviceType(const String& device_type)
{
if (strcmp(device_type.c_str(), "CPU") == 0 || strcmp(device_type.c_str(), "GPU") == 0)
{
if (strcmp(device_type.c_str(), "CPU") == 0)
{
caffe::Caffe::set_mode(caffe::Caffe::CPU);
deviceType = "CPU";
std::cout << "Using CPU" << std::endl;
}
else
{
caffe::Caffe::set_mode(caffe::Caffe::GPU);
deviceType = "GPU";
std::cout << "Using GPU" << std::endl;
}
}
else
{
std::cout << "Error: Device name must be 'GPU' or 'CPU'." << std::endl;
}
};
void descriptorExtractor::setDeviceId(const int& device_id)
{
if (strcmp(deviceType.c_str(), "GPU") == 0)
{
caffe::Caffe::SetDevice(device_id);
deviceId = device_id;
std::cout << "Using GPU with Device ID = " << device_id << std::endl;
}
else
{
std::cout << "Error: Device ID only need to be set when GPU is used." << std::endl;
}
};
void descriptorExtractor::loadNet(const String& model_file, const String& trained_file, const String& mean_file)
{
if (net_set)
{
/* Load the network. */
convnet = new Net<float>(model_file, TEST);
convnet->CopyTrainedLayersFrom(trained_file);
if (convnet->num_inputs() != 1)
std::cout << "Network should have exactly one input." << std::endl;
if (convnet->num_outputs() != 1)
std::cout << "Network should have exactly one output." << std::endl;
Blob<float>* input_layer = convnet->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. */
if (!mean_file.empty())
{
setMean(mean_file);
net_ready = 2;
}
else
{
net_ready = 1;
}
}
else
{
std::cout << "Error: Net is not set properly in advance using construtor." << std::endl;
}
};
/* Load the mean file in binaryproto format. */
void descriptorExtractor::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);
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 descriptorExtractor::extract(InputArrayOfArrays inputimg, OutputArray feature, String feature_blob)
{
if (net_ready)
{
Blob<float>* input_layer = convnet->input_blobs()[0];
input_layer->Reshape(1, num_channels,
input_geometry.height, input_geometry.width);
/* Forward dimension change to all layers. */
convnet->Reshape();
std::vector<cv::Mat> input_channels;
wrapInput(&input_channels);
if (inputimg.kind() == 65536)
{/* this is a Mat */
Mat img = inputimg.getMat();
preprocess(img, &input_channels);
convnet->ForwardPrefilled();
/* Copy the output layer to a std::vector */
Blob<float>* output_layer = convnet->blob_by_name(feature_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);
convnet->ForwardPrefilled();
/* Copy the output layer to a std::vector */
Blob<float>* output_layer = convnet->blob_by_name(feature_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);
}
}
else
std::cout << "Device must be set properly using constructor and the net must be set in advance using loadNet.";
};
/* 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::wrapInput(std::vector<cv::Mat>* input_channels)
{
Blob<float>* input_layer = convnet->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 descriptorExtractor::preprocess(const cv::Mat& img, std::vector<cv::Mat>* input_channels)
{
/* 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 (net_ready == 2)
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)
!= convnet->input_blobs()[0]->cpu_data())
std::cout << "Input channels are not wrapping the input layer of the network." << std::endl;
};
} /* namespace cnn_3dobj */
} /* namespace cv */

@ -0,0 +1,265 @@
#include "precomp.hpp"
using namespace cv;
using namespace std;
namespace cv
{
namespace cnn_3dobj
{
icoSphere::icoSphere(float radius_in, int depth_in)
{
X = 0.5f;
Z = 0.5f;
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 } };
diff = 0.00000001;
X *= (int)radius_in;
Z *= (int)radius_in;
// 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 (unsigned int j = 1; j < CameraPos.size(); ++j)
{
for (unsigned int k = 0; k < j; ++k)
{
float dist_x, dist_y, dist_z;
dist_x = (CameraPos.at(k).x-CameraPos.at(j).x) * (CameraPos.at(k).x-CameraPos.at(j).x);
dist_y = (CameraPos.at(k).y-CameraPos.at(j).y) * (CameraPos.at(k).y-CameraPos.at(j).y);
dist_z = (CameraPos.at(k).z-CameraPos.at(j).z) * (CameraPos.at(k).z-CameraPos.at(j).z);
if (dist_x < diff && dist_y < diff && dist_z < diff)
break;
else 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(unsigned int i = 0; i < 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)
{
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)
{
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)
{
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);
};
int icoSphere::swapEndian(int 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;
}
}
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] = swapEndian(headerimg[i]);
int headerlabel[2] = {2050,num_item};
for (int i=0; i<2; i++)
headerlabel[i] = swapEndian(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, int isrgb)
{
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);
if (isrgb == 0)
{
for (int r = 0; r < ImgforBin.rows; r++)
{
img_file.write(reinterpret_cast<const char*>(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize());
}
}
else
{
std::vector<cv::Mat> Img3forBin;
cv::split(ImgforBin,Img3forBin);
for (unsigned int i = 0; i < Img3forBin.size(); i++)
{
for (int r = 0; r < Img3forBin[i].rows; r++)
{
img_file.write(reinterpret_cast<const char*>(Img3forBin[i].ptr(r)), Img3forBin[i].cols*Img3forBin[i].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;
if (isrgb == 0)
{
for (int r = 0; r < ImgforBin.rows; r++)
{
img_file.write(reinterpret_cast<const char*>(ImgforBin.ptr(r)), ImgforBin.cols*ImgforBin.elemSize());
}
}
else
{
std::vector<cv::Mat> Img3forBin;
cv::split(ImgforBin,Img3forBin);
for (unsigned int i = 0; i < Img3forBin.size(); i++)
{
for (int r = 0; r < Img3forBin[i].rows; r++)
{
img_file.write(reinterpret_cast<const char*>(Img3forBin[i].ptr(r)), Img3forBin[i].cols*Img3forBin[i].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();
};
} /* namespace cnn_3dobj */
} /* namespace cv */

@ -0,0 +1,47 @@
/*
By downloading, copying, installing or using the software you agree to this
license. If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2013, OpenCV Foundation, all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall copyright holders or contributors be liable for
any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_CNN_3DOBJ_PRECOMP_HPP__
#define __OPENCV_CNN_3DOBJ_PRECOMP_HPP__
#include <opencv2/cnn_3dobj.hpp>
#endif

@ -0,0 +1,63 @@
/*
* Created on: Aug 14, 2015
* Author: Yida Wang
*/
#include "test_precomp.hpp"
using namespace cv;
using namespace cv::cnn_3dobj;
class CV_CNN_Feature_Test : public cvtest::BaseTest
{
public:
CV_CNN_Feature_Test();
protected:
void run(int);
};
CV_CNN_Feature_Test::CV_CNN_Feature_Test()
{
}
/**
* This test checks the following:
* Feature extraction by the triplet trained CNN model
*/
void CV_CNN_Feature_Test::run(int)
{
String caffemodel = String(ts->get_data_path()) + "3d_triplet_iter_30000.caffemodel";
String network_forIMG = cvtest::TS::ptr()->get_data_path() + "3d_triplet_testIMG.prototxt";
String mean_file = "no";
std::vector<String> ref_img;
String target_img = String(ts->get_data_path()) + "1_8.png";
String feature_blob = "feat";
String device = "CPU";
int dev_id = 0;
cv::Mat img_base = cv::imread(target_img, -1);
if (img_base.empty())
{
ts->printf(cvtest::TS::LOG, "could not read reference image %s\n", target_img.c_str(), "make sure the path of images are set properly.");
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
cv::cnn_3dobj::descriptorExtractor descriptor(device, dev_id);
if (strcmp(mean_file.c_str(), "no") == 0)
descriptor.loadNet(network_forIMG, caffemodel);
else
descriptor.loadNet(network_forIMG, caffemodel, mean_file);
cv::Mat feature_test;
descriptor.extract(img_base, feature_test, feature_blob);
Mat feature_reference = (Mat_<float>(1,16) << -134.03548, -203.48265, -105.96752, 55.343075, -211.36378, 487.85968, -182.15063, 62.229042, 297.19876, 206.07578, 291.74951, -19.906454, -464.09152, 135.79895, 420.43616, 2.2887282);
printf("Reference feature is computed by Caffe extract_features tool by \n To generate values for different images, use extract_features \n with the resetted image list in prototxt.");
float dist = norm(feature_test - feature_reference);
if (dist > 5) {
ts->printf(cvtest::TS::LOG, "Extracted featrue is not the same from the one extracted from Caffe.");
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
}
TEST(CNN_FEATURE, accuracy) { CV_CNN_Feature_Test test; test.safe_run(); }

@ -0,0 +1,3 @@
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")

@ -0,0 +1,18 @@
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include <iostream>
#include "opencv2/ts.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/cnn_3dobj_config.hpp"
#include "opencv2/cnn_3dobj.hpp"
#endif

@ -0,0 +1,86 @@
name: "3d_triplet"
input: "data"
input_dim: 1
input_dim: 1
input_dim: 64
input_dim: 64
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
convolution_param {
num_output: 16
kernel_size: 8
stride: 1
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "pool1"
top: "pool1"
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
convolution_param {
num_output: 7
kernel_size: 5
stride: 1
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "pool2"
top: "pool2"
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
inner_product_param {
num_output: 256
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "feat"
type: "InnerProduct"
bottom: "ip1"
top: "feat"
inner_product_param {
num_output: 3
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1,52 @@
../../testdata/cv/3d_triplet_iter_1.caffemodel
../../testdata/cv/3d_triplet_iter_2.caffemodel
../../testdata/cv/3d_triplet_iter_3.caffemodel
../../testdata/cv/3d_triplet_iter_4.caffemodel
../../testdata/cv/3d_triplet_iter_5.caffemodel
../../testdata/cv/3d_triplet_iter_6.caffemodel
../../testdata/cv/3d_triplet_iter_7.caffemodel
../../testdata/cv/3d_triplet_iter_8.caffemodel
../../testdata/cv/3d_triplet_iter_9.caffemodel
../../testdata/cv/3d_triplet_iter_10.caffemodel
../../testdata/cv/3d_triplet_iter_20.caffemodel
../../testdata/cv/3d_triplet_iter_30.caffemodel
../../testdata/cv/3d_triplet_iter_40.caffemodel
../../testdata/cv/3d_triplet_iter_50.caffemodel
../../testdata/cv/3d_triplet_iter_60.caffemodel
../../testdata/cv/3d_triplet_iter_70.caffemodel
../../testdata/cv/3d_triplet_iter_80.caffemodel
../../testdata/cv/3d_triplet_iter_90.caffemodel
../../testdata/cv/3d_triplet_iter_100.caffemodel
../../testdata/cv/3d_triplet_iter_200.caffemodel
../../testdata/cv/3d_triplet_iter_300.caffemodel
../../testdata/cv/3d_triplet_iter_400.caffemodel
../../testdata/cv/3d_triplet_iter_500.caffemodel
../../testdata/cv/3d_triplet_iter_600.caffemodel
../../testdata/cv/3d_triplet_iter_700.caffemodel
../../testdata/cv/3d_triplet_iter_800.caffemodel
../../testdata/cv/3d_triplet_iter_900.caffemodel
../../testdata/cv/3d_triplet_iter_1000.caffemodel
../../testdata/cv/3d_triplet_iter_2000.caffemodel
../../testdata/cv/3d_triplet_iter_3000.caffemodel
../../testdata/cv/3d_triplet_iter_4000.caffemodel
../../testdata/cv/3d_triplet_iter_5000.caffemodel
../../testdata/cv/3d_triplet_iter_6000.caffemodel
../../testdata/cv/3d_triplet_iter_7000.caffemodel
../../testdata/cv/3d_triplet_iter_8000.caffemodel
../../testdata/cv/3d_triplet_iter_9000.caffemodel
../../testdata/cv/3d_triplet_iter_10000.caffemodel
../../testdata/cv/3d_triplet_iter_20000.caffemodel
../../testdata/cv/3d_triplet_iter_30000.caffemodel
../../testdata/cv/3d_triplet_iter_40000.caffemodel
../../testdata/cv/3d_triplet_iter_50000.caffemodel
../../testdata/cv/3d_triplet_iter_60000.caffemodel
../../testdata/cv/3d_triplet_iter_70000.caffemodel
../../testdata/cv/3d_triplet_iter_110000.caffemodel
../../testdata/cv/3d_triplet_iter_120000.caffemodel
../../testdata/cv/3d_triplet_iter_130000.caffemodel
../../testdata/cv/3d_triplet_iter_140000.caffemodel
../../testdata/cv/3d_triplet_iter_150000.caffemodel
../../testdata/cv/3d_triplet_iter_160000.caffemodel
../../testdata/cv/3d_triplet_iter_170000.caffemodel
../../testdata/cv/3d_triplet_iter_180000.caffemodel
../../testdata/cv/3d_triplet_iter_190000.caffemodel

@ -0,0 +1,75 @@
Training data generation using Icosphere {#tutorial_data_generation}
=============
Goal
----
In this tutorial you will learn how to
- Conduct a point cloud of camera view on sphere.
- Generate training images using 3D model.
Code
----
You can download the code from [here ](https://github.com/Wangyida/opencv_contrib/blob/cnn_3dobj/samples/demo_sphereview_data.cpp).
@include cnn_3dobj/samples/demo_sphereview_data.cpp
Explanation
-----------
Here is the general structure of the program:
- Create a window.
@code{.cpp}
viz::Viz3d myWindow("Coordinate Frame");
@endcode
- Set window size as 64*64, we use this scale as default.
@code{.cpp}
myWindow.setWindowSize(Size(64,64));
@endcode
- Add coordinate axes.
@code{.cpp}
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
myWindow.setBackgroundColor(viz::Color::gray());
myWindow.spin();
@endcode
- Create a Mesh widget, loading .ply models.
@code{.cpp}
viz::Mesh objmesh = viz::Mesh::load(plymodel);
@endcode
- Get the center of the generated mesh widget, cause some .ply files.
@code{.cpp}
Point3d cam_focal_point = ViewSphere.getCenter(objmesh.cloud);
@endcode
- Get the pose of the camera using makeCameraPoses.
@code{.cpp}
Affine3f cam_pose = viz::makeCameraPose(campos.at(pose)*radius+cam_focal_point, cam_focal_point, cam_y_dir*radius+cam_focal_point);
@endcode
- Get the transformation matrix from camera coordinate system to global.
@code{.cpp}
Affine3f transform = viz::makeTransformToGlobal(Vec3f(1.0f,0.0f,0.0f), Vec3f(0.0f,1.0f,0.0f), Vec3f(0.0f,0.0f,1.0f), campos.at(pose));
viz::WMesh mesh_widget(objmesh);
@endcode
- Save screen shot as images.
@code{.cpp}
myWindow.saveScreenshot(filename);
@endcode
- Write images into binary files for further using in CNN training.
@code{.cpp}
ViewSphere.writeBinaryfile(filename, binaryPath, headerPath,(int)campos.size()*num_class, label_class, (int)(campos.at(pose).x*100), (int)(campos.at(pose).y*100), (int)(campos.at(pose).z*100), rgb_use);
@endcode
Results
-------
Here is collection images created by this demo using 4 model.
![](images_all/1_8.png)

@ -0,0 +1,66 @@
Classify {#tutorial_classify}
===============
Goal
----
In this tutorial you will learn how to
- How to extract feature from an image
- How to extract features from images under a given root path
- How to make a prediction using reference images and target image
Code
----
You can download the code from [here ](https://github.com/Wangyida/opencv_contrib/blob/cnn_3dobj/samples/demo_classify.cpp).
@include cnn_3dobj/samples/demo_classify.cpp
Explanation
-----------
Here is the general structure of the program:
- Initialize a net work with Device.
@code{.cpp}
cv::cnn_3dobj::descriptorExtractor descriptor(device);
@endcode
- Load net with the caffe trained net work parameter and structure.
@code{.cpp}
if (strcmp(mean_file.c_str(), "no") == 0)
descriptor.loadNet(network_forIMG, caffemodel);
else
descriptor.loadNet(network_forIMG, caffemodel, mean_file);
@endcode
- List the file names under a given path.
@code{.cpp}
listDir(src_dir.c_str(), name_gallery, false);
for (unsigned int i = 0; i < name_gallery.size(); i++)
{
name_gallery[i] = src_dir + name_gallery[i];
}
@endcode
- Extract feature from a set of images.
@code{.cpp}
descriptor.extract(img_gallery, feature_reference, feature_blob);
@endcode
- Initialize a matcher which using L2 distance.
@code{.cpp}
cv::BFMatcher matcher(NORM_L2);
std::vector<std::vector<cv::DMatch> > matches;
@endcode
- Have a KNN match on the target and reference images.
@code{.cpp}
matcher.knnMatch(feature_test, feature_reference, matches, num_candidate);
@endcode
- Print features of the reference images.
@code{.cpp}std::cout << std::endl << "---------- Features of target image: " << target_img << "----------" << endl << feature_test << std::endl;
@endcode
Results
-------

@ -0,0 +1,60 @@
Training data generation using Icosphere {#tutorial_model_analysis}
=============
Goal
----
In this tutorial you will learn how to
- Extract feature from particular image.
- Have a meaningful comparation on the extracted feature.
Code
----
You can download the code from [here ](https://github.com/Wangyida/opencv_contrib/blob/cnn_3dobj/samples/demo_model_analysis.cpp).
@include cnn_3dobj/samples/demo_model_analysis.cpp
Explanation
-----------
Here is the general structure of the program:
- Sample which is most closest in pose to reference image and also the same class.
@code{.cpp}
ref_img.push_back(ref_img1);
@endcode
- Sample which is less closest in pose to reference image and also the same class.
@code{.cpp}
ref_img.push_back(ref_img2);
@endcode
- Sample which is very close in pose to reference image but not the same class.
@code{.cpp}
ref_img.push_back(ref_img3);
@endcode
- Initialize a net work with Device.
@code{.cpp}
cv::cnn_3dobj::descriptorExtractor descriptor(device, dev_id);
@endcode
- Load net with the caffe trained net work parameter and structure.
@code{.cpp}
if (strcmp(mean_file.c_str(), "no") == 0)
descriptor.loadNet(network_forIMG, caffemodel);
else
descriptor.loadNet(network_forIMG, caffemodel, mean_file);
@endcode
- Have comparations on the distance between reference image and 3 other images
distance between closest sample and reference image should be smallest and
distance between sample in another class and reference image should be largest.
@code{.cpp}
if (matches[0] < matches[1] && matches[0] < matches[2])
pose_pass = true;
if (matches[1] < matches[2])
class_pass = true;
@endcode
Results
-------

@ -0,0 +1,26 @@
CNN for 3D Object Classification and Pose Estimation {#tutorial_table_of_content_cnn_3dobj}
==========
- @subpage tutorial_data_generation
*Compatibility:* \> OpenCV 3.0.0
*Author:* Yida Wang
You will learn how to generate training images from 3D models with proper poses for CNN training.
- @subpage tutorial_feature_classification
*Compatibility:* \> OpenCV 3.0.0
*Author:* Yida Wang
You will learn how to extract features from images and make a prediction using descriptor.
- @subpage tutorial_model_analysis
*Compatibility:* \> OpenCV 3.0.0
*Author:* Yida Wang
You will learn how to have an analysis on performance of the trained Model.
Loading…
Cancel
Save