diff --git a/modules/cnn_3dobj/CMakeLists.txt b/modules/cnn_3dobj/CMakeLists.txt index 2285ecf9c..eb1f3ba4d 100644 --- a/modules/cnn_3dobj/CMakeLists.txt +++ b/modules/cnn_3dobj/CMakeLists.txt @@ -1,3 +1,26 @@ -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 caffe protobuf glog OPTIONAL WRAP python) -target_link_libraries(opencv_cnn_3dobj caffe protobuf glog) +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() + +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}) +endif() +endif() diff --git a/modules/cnn_3dobj/FindCaffe.cmake b/modules/cnn_3dobj/FindCaffe.cmake new file mode 100644 index 000000000..12948f629 --- /dev/null +++ b/modules/cnn_3dobj/FindCaffe.cmake @@ -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() diff --git a/modules/cnn_3dobj/cnn_3dobj_config.hpp.in b/modules/cnn_3dobj/cnn_3dobj_config.hpp.in new file mode 100644 index 000000000..ad30a32f7 --- /dev/null +++ b/modules/cnn_3dobj/cnn_3dobj_config.hpp.in @@ -0,0 +1,5 @@ +#ifndef __OPENCV_CNN_3DOBJ_CONFIG_HPP__ +#define __OPENCV_CNN_3DOBJ_CONFIG_HPP__ +// HAVE CAFFE +#cmakedefine HAVE_CAFFE +#endif diff --git a/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp b/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp index 1b3186c14..a5ee9259b 100644 --- a/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp +++ b/modules/cnn_3dobj/include/opencv2/cnn_3dobj.hpp @@ -58,12 +58,16 @@ the use of this software, even if advised of the possibility of such damage. #include #include #define CPU_ONLY -#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" + +#ifdef HAVE_CAFFE +#include +#include +#include +#include +#include +#include +#endif + #include "opencv2/viz/vizcore.hpp" #include "opencv2/highgui.hpp" #include "opencv2/highgui/highgui_c.h" @@ -132,10 +136,10 @@ class CV_EXPORTS_W IcoSphere }; -class CV_EXPORTS_W Classification +class CV_EXPORTS_W Feature { private: - caffe::shared_ptr > net_; + caffe::Net* net_; cv::Size input_geometry_; int num_channels_; cv::Mat mean_; @@ -150,7 +154,7 @@ class CV_EXPORTS_W Classification /** @brief Convert the input image to the input image format of the network. */ public: - Classification(); + Feature(); void list_dir(const char *path,std::vector& files,bool r); /** @brief Get the file name from a root dictionary. */ diff --git a/modules/cnn_3dobj/include/opencv2/cnn_3dobj_config.hpp b/modules/cnn_3dobj/include/opencv2/cnn_3dobj_config.hpp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/cnn_3dobj/samples/classifyIMG_demo.cpp b/modules/cnn_3dobj/samples/classifyIMG_demo.cpp index c17bb275f..b368e9bf6 100644 --- a/modules/cnn_3dobj/samples/classifyIMG_demo.cpp +++ b/modules/cnn_3dobj/samples/classifyIMG_demo.cpp @@ -32,6 +32,7 @@ * POSSIBILITY OF SUCH DAMAGE. * */ +#define HAVE_CAFFE #include #include using namespace cv; @@ -50,7 +51,7 @@ int main(int argc, char** argv) "{device | CPU | device}" "{dev_id | 0 | dev_id}"; cv::CommandLineParser parser(argc, argv, keys); - parser.about("Demo for Sphere View data generation"); + parser.about("Demo for object data classification and pose estimation"); if (parser.has("help")) { parser.printMessage(); diff --git a/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp b/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp index 0718128be..7e547ec6d 100644 --- a/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp +++ b/modules/cnn_3dobj/samples/sphereview_3dobj_demo.cpp @@ -32,6 +32,7 @@ * POSSIBILITY OF SUCH DAMAGE. * */ +#define HAVE_CAFFE #include #include #include diff --git a/modules/cnn_3dobj/src/cnn_classification.cpp b/modules/cnn_3dobj/src/cnn_feature.cpp similarity index 88% rename from modules/cnn_3dobj/src/cnn_classification.cpp rename to modules/cnn_3dobj/src/cnn_feature.cpp index 029f3aa74..c3a599d44 100644 --- a/modules/cnn_3dobj/src/cnn_classification.cpp +++ b/modules/cnn_3dobj/src/cnn_feature.cpp @@ -6,8 +6,8 @@ namespace cv { namespace cnn_3dobj { - Classification::Classification(){}; - void Classification::list_dir(const char *path,vector& files,bool r) + Feature::Feature(){}; + void Feature::list_dir(const char *path,vector& files,bool r) { DIR *pDir; struct dirent *ent; @@ -25,7 +25,7 @@ namespace cnn_3dobj if(r) { sprintf(childpath, "%s/%s", path, ent->d_name); - Classification::list_dir(childpath,files,false); + Feature::list_dir(childpath,files,false); } } else @@ -36,7 +36,7 @@ namespace cnn_3dobj sort(files.begin(),files.end()); }; - void Classification::NetSetter(const string& model_file, const string& trained_file, const string& mean_file, const string& cpu_only, int device_id) + void Feature::NetSetter(const string& model_file, const string& trained_file, const string& mean_file, const string& cpu_only, int device_id) { if (strcmp(cpu_only.c_str(), "CPU") == 0) { @@ -48,7 +48,7 @@ namespace cnn_3dobj caffe::Caffe::SetDevice(device_id); } /* Load the network. */ - net_.reset(new Net(model_file, TEST)); + net_ = new Net(model_file, TEST); net_->CopyTrainedLayersFrom(trained_file); CHECK_EQ(net_->num_inputs(), 1) << "Network should have exactly one input."; CHECK_EQ(net_->num_outputs(), 1) << "Network should have exactly one output."; @@ -61,14 +61,14 @@ namespace cnn_3dobj SetMean(mean_file); }; - void Classification::GetLabellist(const std::vector& name_gallery) + void Feature::GetLabellist(const std::vector& name_gallery) { for (unsigned int i = 0; i < name_gallery.size(); ++i) labels_.push_back(name_gallery[i]); }; /* Return the indices of the top N values of vector v. */ - std::vector Classification::Argmax(const std::vector& v, int N) + std::vector Feature::Argmax(const std::vector& v, int N) { std::vector > pairs; for (size_t i = 0; i < v.size(); ++i) @@ -81,7 +81,7 @@ namespace cnn_3dobj }; //Return the top N predictions. - std::vector > Classification::Classify(const cv::Mat& reference, const cv::Mat& target, int N) + std::vector > Feature::Classify(const cv::Mat& reference, const cv::Mat& target, int N) { std::vector output; for (int i = 0; i < reference.rows; i++) @@ -102,7 +102,7 @@ namespace cnn_3dobj }; /* Load the mean file in binaryproto format. */ - void Classification::SetMean(const string& mean_file) + void Feature::SetMean(const string& mean_file) { BlobProto blob_proto; ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto); @@ -130,7 +130,7 @@ namespace cnn_3dobj mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean); }; - void Classification::FeatureExtract(InputArray inputimg, OutputArray feature, bool mean_subtract, std::string featrue_blob) + void Feature::FeatureExtract(InputArray inputimg, OutputArray feature, bool mean_subtract, std::string featrue_blob) { Blob* input_layer = net_->input_blobs()[0]; input_layer->Reshape(1, num_channels_, @@ -183,7 +183,7 @@ namespace cnn_3dobj * don't need to rely on cudaMemcpy2D. The last preprocessing * operation will write the separate channels directly to the input * layer. */ - void Classification::WrapInputLayer(std::vector* input_channels) + void Feature::WrapInputLayer(std::vector* input_channels) { Blob* input_layer = net_->input_blobs()[0]; int width = input_layer->width(); @@ -197,7 +197,7 @@ namespace cnn_3dobj } }; - void Classification::Preprocess(const cv::Mat& img, + void Feature::Preprocess(const cv::Mat& img, std::vector* input_channels, bool mean_subtract) { /* Convert the input image to the input image format of the network. */ diff --git a/modules/cnn_3dobj/src/precomp.hpp b/modules/cnn_3dobj/src/precomp.hpp index cdd5e11bf..54dd266f5 100644 --- a/modules/cnn_3dobj/src/precomp.hpp +++ b/modules/cnn_3dobj/src/precomp.hpp @@ -42,6 +42,7 @@ 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 #include #endif