Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
12bdc2af
Commit
12bdc2af
authored
Mar 21, 2017
by
Vladislav Sovrasov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dnn_modern: update docs, fix build problems
parent
63f6f18f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
121 additions
and
73 deletions
+121
-73
CMakeLists.txt
modules/dnn_modern/CMakeLists.txt
+34
-6
README.md
modules/dnn_modern/README.md
+13
-7
FindTinyDNN.cmake
modules/dnn_modern/cmake/FindTinyDNN.cmake
+1
-0
dnn_modern.hpp
modules/dnn_modern/include/opencv2/dnn_modern.hpp
+26
-16
simple_test.cpp
modules/dnn_modern/samples/simple_test.cpp
+3
-1
caffe_converter.cpp
modules/dnn_modern/src/caffe_converter.cpp
+44
-43
No files found.
modules/dnn_modern/CMakeLists.txt
View file @
12bdc2af
...
...
@@ -15,6 +15,23 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# MODULE REQUIREMENTS
# ----------------------------------------------------------------------------
set
(
TINY_DNN_CPP_PATH
"
${
OpenCV_BINARY_DIR
}
/3rdparty/tinydnn"
)
set
(
TINY_DNN_CPP_ROOT
"
${
TINY_DNN_CPP_PATH
}
/tiny-dnn-1.0.0a3"
)
ocv_download
(
FILENAME
"v1.0.0a3.tar.gz"
HASH
"adb1c512e09ca2c7a6faef36f9c53e59"
URL
"
${
OPENCV_TINY_DNN_URL
}
"
"$ENV{OPENCV_TINY_DNN_URL}"
"https://github.com/tiny-dnn/tiny-dnn/archive/"
DESTINATION_DIR
"
${
TINY_DNN_CPP_PATH
}
"
STATUS TINY_DNN_DOWNLOAD_SUCCESS
ID
"tiny-dnn"
UNPACK RELATIVE_URL
)
if
(
NOT TINY_DNN_DOWNLOAD_SUCCESS
)
message
(
STATUS
"Failed to download tiny-dnn sources"
)
endif
()
find_package
(
TinyDNN QUIET
)
include
(
CheckCXXCompilerFlag
)
...
...
@@ -59,12 +76,22 @@ if(TINYDNN_USE_NNPACK)
list
(
APPEND REQUIRED_LIBRARIES
${
NNPACK_LIB
}
)
endif
()
# we need to disable seializer unless we import cereal
add_definitions
(
-DCNN_NO_SERIALIZATION
)
# we need to disable seializer unless we import cereal
and we gonna use caffe converter
add_definitions
(
-DCNN_NO_SERIALIZATION
-DCNN_USE_CAFFE_CONVERTER
)
# NOTE: In case that proto files already exist,
# this is not needed anymore.
find_package
(
Protobuf
)
find_package
(
Protobuf QUIET
)
if
(
DEFINED PROTOBUF_PROTOC_EXECUTABLE AND EXISTS
${
PROTOBUF_PROTOC_EXECUTABLE
}
)
execute_process
(
COMMAND
${
PROTOBUF_PROTOC_EXECUTABLE
}
caffe.proto --cpp_out=./
WORKING_DIRECTORY
${
TINYDNN_INCLUDE_DIRS
}
/tiny_dnn/io/caffe
)
else
()
message
(
STATUS
"The protocol buffer compiler is not found (PROTOBUF_PROTOC_EXECUTABLE='
${
PROTOBUF_PROTOC_EXECUTABLE
}
')"
)
ocv_module_disable
(
dnn_modern
)
return
()
endif
()
list
(
APPEND REQUIRED_LIBRARIES
${
PROTOBUF_LIBRARIES
}
)
####
...
...
@@ -76,7 +103,6 @@ list(APPEND REQUIRED_LIBRARIES ${PROTOBUF_LIBRARIES})
set
(
CMAKE_CXX_STANDARD 11
)
set
(
CMAKE_CXX_STANDARD_REQUIRED ON
)
message
(
STATUS
"C++11 support has been enabled by default."
)
# Unix
if
(
CMAKE_COMPILER_IS_GNUCXX OR MINGW OR
...
...
@@ -138,7 +164,9 @@ endif()
# DNN-MODERN MODULE
# ----------------------------------------------------------------------------
ocv_define_module
(
dnn_modern opencv_core opencv_imgproc
opencv_imgcodecs
WRAP python
)
ocv_define_module
(
dnn_modern opencv_core opencv_imgproc WRAP python
)
ocv_target_link_libraries
(
${
the_module
}
${
REQUIRED_LIBRARIES
}
)
ocv_target_include_directories
(
${
the_module
}
${
TINYDNN_INCLUDE_DIRS
}
)
target_compile_options
(
${
the_module
}
PRIVATE
"-Wno-error=non-virtual-dtor"
)
ocv_warnings_disable
(
CMAKE_CXX_FLAGS
-Wnon-virtual-dtor -Wunused-parameter -Wshadow -Wundef
/wd4265 /wd4100 /wd4458 /wd4244 /wd4456
)
modules/dnn_modern/README.md
View file @
12bdc2af
Modern Deep Learning Module
===========================
The module is wrapper to
[
tiny-dnn
](
https://github.com/tiny-dnn/tiny-dnn
)
A header only, dependency-free deep learning framework in C++11
The module is wrapper to
[
tiny-dnn
](
https://github.com/tiny-dnn/tiny-dnn
)
,
a header only, dependency-free deep learning framework in C++11.
Installation
------------
...
...
@@ -12,19 +11,24 @@ Installation
-
System under Unix or Windows
-
C++11 compiler
-
tiny-dnn headers
-
protoc compiler (part of the
[
protobuf
](
https://developers.google.com/protocol-buffers/docs/overview
)
library)
**How to install tiny-dnn?**
CMake will try to download a certain version of tiny-dnn which was tested to build with OpenCV.
If the latest version is needed, location of the tiny-dnn folder can be specified manually:
Download tiny-dnn project somewhere in your system
-
Download tiny-dnn project somewhere in your system
```
cd /opt
git clone https://github.com/tiny-dnn/tiny-dnn.git
```
Run your OpenCV CMake pointing to your tiny-dnn headers location
-
Run your OpenCV CMake pointing to your tiny-dnn headers location
```
cd /opt/opencv/build
cmake -DTINYDNN_ROOT=/opt/tiny-dnn ..
make -j4
```
**Extra**
...
...
@@ -42,3 +46,5 @@ Installation
Check project site for installation:
[
https://github.com/Maratyszcza/NNPACK
](
https://github.com/Maratyszcza/NNPACK
)
cmake -DTINYDNN_USE_NNPACK=ON .. // not supported yet for Caffe loader
See detailed module API documentation in http://docs.opencv.org/trunk/d1/df7/group__dnn__modern.html
modules/dnn_modern/cmake/FindTinyDNN.cmake
View file @
12bdc2af
...
...
@@ -19,6 +19,7 @@ set(TINYDNN_INCLUDE_SEARCH_PATHS
$ENV{TINYDNN_ROOT}
${
TINYDNN_ROOT
}
${
TINYDNN_ROOT
}
/tiny_dnn
${
TINY_DNN_CPP_ROOT
}
)
find_path
(
TINYDNN_INCLUDE_DIR
...
...
modules/dnn_modern/include/opencv2/dnn_modern.hpp
View file @
12bdc2af
...
...
@@ -46,25 +46,33 @@
#define __OPENCV_DNN_M_HPP__
#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
/** @defgroup dnn_modern Deep Learning Modern Module
@{
Base class for tiny-dnn converter
@}
* This module is based on the [tiny-dnn](https://github.com/tiny-dnn/tiny-dnn) framework.
* The module uses tiny-dnn to load and run pre-trained Caffe models.
* tiny-dnn's converter only supports single input/single output network without branches.
*/
namespace
cv
{
namespace
dnn2
{
//! @addtogroup dnn_modern
//! @{
/** @brief Base class for tiny-dnn converter.
*/
class
CV_EXPORTS_W
BaseConverter
{
public
:
virtual
~
BaseConverter
()
{};
virtual
void
eval
(
const
cv
::
InputArray
image
,
std
::
vector
<
float_t
>*
results
)
=
0
;
/**
@brief Evaluates single model output on single model input.
@param image input image.
@param results output form model.
*/
CV_WRAP
virtual
void
eval
(
InputArray
image
,
std
::
vector
<
float
>&
results
)
=
0
;
};
/** @brief Class implementing the CaffeConverter.
...
...
@@ -77,20 +85,22 @@ class CV_EXPORTS_W CaffeConverter : public BaseConverter {
public
:
/**
@param model_file path to the prototxt file.
@param trained_file path to the caffemodel file.
@param mean_file path to binaryproto file.
@brief Creates a CaffeConverter object.
@param model_file path to the prototxt file.
@param trained_file path to the caffemodel file.
@param mean_file path to binaryproto file.
*/
CV_WRAP
static
Ptr
<
CaffeConverter
>
create
(
const
cv
::
String
&
model_file
,
const
cv
::
String
&
trained_file
,
const
cv
::
String
&
mean_file
=
cv
::
String
());
CV_WRAP
static
Ptr
<
CaffeConverter
>
create
(
const
String
&
model_file
,
const
String
&
trained_file
,
const
String
&
mean_file
=
String
());
virtual
void
eval
(
const
cv
::
InputArray
image
,
std
::
vector
<
float_t
>*
results
)
=
0
;
CV_WRAP
virtual
void
eval
(
InputArray
image
,
CV_OUT
std
::
vector
<
float
>&
results
)
=
0
;
};
//! @}
}
// namespace dnn2
}
// namespace cv
#endif
/* End of file. */
modules/dnn_modern/samples/simple_test.cpp
View file @
12bdc2af
#include <opencv2/dnn_modern.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <fstream>
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
::
dnn2
;
...
...
@@ -79,7 +81,7 @@ int main(int argc, char* argv[]) {
// inference !
vector
<
float_t
>
scores
;
caffe_ptr
->
eval
(
img
,
&
scores
);
caffe_ptr
->
eval
(
img
,
scores
);
// retrieve n labels
const
int
n
=
5
;
...
...
modules/dnn_modern/src/caffe_converter.cpp
View file @
12bdc2af
...
...
@@ -43,9 +43,10 @@
*/
#include "precomp.hpp"
#include <opencv2/imgproc.hpp>
#define CNN_USE_CAFFE_CONVERTER
#include <tiny_dnn/tiny_dnn.h>
#include <tiny_dnn/io/caffe/caffe.pb.cc>
using
namespace
tiny_dnn
;
using
namespace
tiny_dnn
::
activation
;
...
...
@@ -59,9 +60,9 @@ namespace dnn2 {
*/
class
CaffeConverter_Impl
:
public
CaffeConverter
{
public
:
explicit
CaffeConverter_Impl
(
const
cv
::
String
&
model_file
,
const
cv
::
String
&
trained_file
,
const
cv
::
String
&
mean_file
)
{
explicit
CaffeConverter_Impl
(
const
String
&
model_file
,
const
String
&
trained_file
,
const
String
&
mean_file
)
{
net_
=
create_net_from_caffe_prototxt
(
model_file
);
reload_weight_from_caffe_protobinary
(
trained_file
,
net_
.
get
());
...
...
@@ -73,31 +74,31 @@ class CaffeConverter_Impl : public CaffeConverter {
~
CaffeConverter_Impl
()
{}
virtual
void
eval
(
const
cv
::
InputArray
image
,
std
::
vector
<
float
>*
results
);
virtual
void
eval
(
InputArray
image
,
std
::
vector
<
float
>&
results
);
private
:
cv
::
Mat
compute_mean
(
const
string
&
mean_file
,
const
size_t
width
,
Mat
compute_mean
(
const
string
&
mean_file
,
const
size_t
width
,
const
size_t
height
);
cv
::
ColorConversionCodes
get_cvt_codes
(
const
int
src_channels
,
ColorConversionCodes
get_cvt_codes
(
const
int
src_channels
,
const
int
dst_channels
);
void
preprocess
(
const
cv
::
Mat
&
img
,
const
cv
::
Mat
&
mean
,
const
int
num_channels
,
const
cv
::
Size
&
geometry
,
vector
<
cv
::
Mat
>*
input_channels
);
void
preprocess
(
const
Mat
&
img
,
const
Mat
&
mean
,
const
int
num_channels
,
const
Size
&
geometry
,
vector
<
Mat
>*
input_channels
);
cv
::
Mat
mean_
;
Mat
mean_
;
std
::
shared_ptr
<
network
<
sequential
>>
net_
;
};
cv
::
Mat
Mat
CaffeConverter_Impl
::
compute_mean
(
const
string
&
mean_file
,
const
size_t
width
,
const
size_t
height
)
{
caffe
::
BlobProto
blob
;
::
detail
::
read_proto_from_binary
(
mean_file
,
&
blob
);
vector
<
cv
::
Mat
>
channels
;
vector
<
Mat
>
channels
;
auto
data
=
blob
.
mutable_data
()
->
mutable_data
();
const
size_t
offset
=
blob
.
height
()
*
blob
.
width
();
...
...
@@ -106,69 +107,69 @@ CaffeConverter_Impl::compute_mean(const string& mean_file,
channels
.
emplace_back
(
blob
.
height
(),
blob
.
width
(),
CV_32FC1
,
data
);
}
cv
::
Mat
mean
;
cv
::
merge
(
channels
,
mean
);
Mat
meanChannel
;
merge
(
channels
,
meanChannel
);
return
cv
::
Mat
(
cv
::
Size
(
width
,
height
),
mean
.
type
(),
cv
::
mean
(
mean
));
return
Mat
(
Size
(
width
,
height
),
meanChannel
.
type
(),
mean
(
meanChannel
));
}
cv
::
ColorConversionCodes
ColorConversionCodes
CaffeConverter_Impl
::
get_cvt_codes
(
const
int
src_channels
,
const
int
dst_channels
)
{
assert
(
src_channels
!=
dst_channels
);
if
(
dst_channels
==
3
)
{
return
src_channels
==
1
?
cv
::
COLOR_GRAY2BGR
:
cv
::
COLOR_BGRA2BGR
;
return
src_channels
==
1
?
COLOR_GRAY2BGR
:
COLOR_BGRA2BGR
;
}
else
if
(
dst_channels
==
1
)
{
return
src_channels
==
3
?
cv
::
COLOR_BGR2GRAY
:
cv
::
COLOR_BGRA2GRAY
;
return
src_channels
==
3
?
COLOR_BGR2GRAY
:
COLOR_BGRA2GRAY
;
}
else
{
throw
runtime_error
(
"unsupported color code"
);
}
}
void
CaffeConverter_Impl
::
preprocess
(
const
cv
::
Mat
&
img
,
const
cv
::
Mat
&
mean
,
void
CaffeConverter_Impl
::
preprocess
(
const
Mat
&
img
,
const
Mat
&
mean
,
const
int
num_channels
,
const
cv
::
Size
&
geometry
,
vector
<
cv
::
Mat
>*
input_channels
)
{
cv
::
Mat
sample
;
const
Size
&
geometry
,
vector
<
Mat
>*
input_channels
)
{
Mat
sample
;
// convert color
if
(
img
.
channels
()
!=
num_channels
)
{
cv
::
cv
tColor
(
img
,
sample
,
cvtColor
(
img
,
sample
,
get_cvt_codes
(
img
.
channels
(),
num_channels
));
}
else
{
sample
=
img
;
}
// resize
cv
::
Mat
sample_resized
;
cv
::
resize
(
sample
,
sample_resized
,
geometry
);
Mat
sample_resized
;
resize
(
sample
,
sample_resized
,
geometry
);
cv
::
Mat
sample_float
;
Mat
sample_float
;
sample_resized
.
convertTo
(
sample_float
,
num_channels
==
3
?
CV_32FC3
:
CV_32FC1
);
// subtract mean
if
(
mean
.
size
().
width
>
0
)
{
cv
::
Mat
sample_normalized
;
cv
::
subtract
(
sample_float
,
mean
,
sample_normalized
);
cv
::
split
(
sample_normalized
,
*
input_channels
);
Mat
sample_normalized
;
subtract
(
sample_float
,
mean
,
sample_normalized
);
split
(
sample_normalized
,
*
input_channels
);
}
else
{
cv
::
split
(
sample_float
,
*
input_channels
);
split
(
sample_float
,
*
input_channels
);
}
}
void
CaffeConverter_Impl
::
eval
(
const
cv
::
InputArray
image
,
std
::
vector
<
float
>
*
results
)
{
const
cv
::
Mat
img
=
image
.
getMat
();
void
CaffeConverter_Impl
::
eval
(
InputArray
image
,
std
::
vector
<
float
>
&
results
)
{
const
Mat
img
=
image
.
getMat
();
const
size_t
channels
=
(
*
net_
)[
0
]
->
in_data_shape
()[
0
].
depth_
;
const
size_t
width
=
(
*
net_
)[
0
]
->
in_data_shape
()[
0
].
width_
;
const
size_t
height
=
(
*
net_
)[
0
]
->
in_data_shape
()[
0
].
height_
;
vector
<
cv
::
Mat
>
input_channels
;
vector
<
Mat
>
input_channels
;
vector
<
float
>
inputvec
(
width
*
height
*
channels
);
for
(
size_t
i
=
0
;
i
<
channels
;
i
++
)
{
...
...
@@ -177,7 +178,7 @@ void CaffeConverter_Impl::eval(const cv::InputArray image,
}
// subtract mean from input
preprocess
(
img
,
mean_
,
3
,
cv
::
Size
(
width
,
height
),
&
input_channels
);
preprocess
(
img
,
mean_
,
3
,
Size
(
width
,
height
),
&
input_channels
);
const
vector
<
tiny_dnn
::
float_t
>
vec
(
inputvec
.
begin
(),
inputvec
.
end
());
...
...
@@ -185,17 +186,17 @@ void CaffeConverter_Impl::eval(const cv::InputArray image,
auto
result
=
net_
->
predict
(
vec
);
// allocate output
results
->
clear
();
results
->
reserve
(
result
.
size
());
results
.
clear
();
results
.
reserve
(
result
.
size
());
for
(
size_t
i
=
0
;
i
<
result
.
size
();
i
++
)
{
results
->
push_back
(
result
[
i
]);
results
.
push_back
(
result
[
i
]);
}
}
Ptr
<
CaffeConverter
>
CaffeConverter
::
create
(
const
cv
::
String
&
model_file
,
const
cv
::
String
&
trained_file
,
const
cv
::
String
&
mean_file
)
{
Ptr
<
CaffeConverter
>
CaffeConverter
::
create
(
const
String
&
model_file
,
const
String
&
trained_file
,
const
String
&
mean_file
)
{
return
makePtr
<
CaffeConverter_Impl
>
(
model_file
,
trained_file
,
mean_file
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment