mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -644,6 +644,24 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromDarknet(const String &cfgFile, const String &darknetModel = String());
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://pjreddie.com/darknet/">Darknet</a> model files.
|
||||
* @param bufferCfg A buffer contains a content of .cfg file with text description of the network architecture.
|
||||
* @param bufferModel A buffer contains a content of .weights file with learned network.
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromDarknet(const std::vector<uchar>& bufferCfg,
|
||||
const std::vector<uchar>& bufferModel = std::vector<uchar>());
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://pjreddie.com/darknet/">Darknet</a> model files.
|
||||
* @param bufferCfg A buffer contains a content of .cfg file with text description of the network architecture.
|
||||
* @param lenCfg Number of bytes to read from bufferCfg
|
||||
* @param bufferModel A buffer contains a content of .weights file with learned network.
|
||||
* @param lenModel Number of bytes to read from bufferModel
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS Net readNetFromDarknet(const char *bufferCfg, size_t lenCfg,
|
||||
const char *bufferModel = NULL, size_t lenModel = 0);
|
||||
|
||||
/** @brief Reads a network model stored in <a href="http://caffe.berkeleyvision.org">Caffe</a> framework's format.
|
||||
* @param prototxt path to the .prototxt file with text description of the network architecture.
|
||||
* @param caffeModel path to the .caffemodel file with learned network.
|
||||
@@ -651,6 +669,14 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromCaffe(const String &prototxt, const String &caffeModel = String());
|
||||
|
||||
/** @brief Reads a network model stored in Caffe model in memory.
|
||||
* @param bufferProto buffer containing the content of the .prototxt file
|
||||
* @param bufferModel buffer containing the content of the .caffemodel file
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromCaffe(const std::vector<uchar>& bufferProto,
|
||||
const std::vector<uchar>& bufferModel = std::vector<uchar>());
|
||||
|
||||
/** @brief Reads a network model stored in Caffe model in memory.
|
||||
* @details This is an overloaded member function, provided for convenience.
|
||||
* It differs from the above function only in what argument(s) it accepts.
|
||||
@@ -672,6 +698,14 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromTensorflow(const String &model, const String &config = String());
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://www.tensorflow.org/">TensorFlow</a> framework's format.
|
||||
* @param bufferModel buffer containing the content of the pb file
|
||||
* @param bufferConfig buffer containing the content of the pbtxt file
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNetFromTensorflow(const std::vector<uchar>& bufferModel,
|
||||
const std::vector<uchar>& bufferConfig = std::vector<uchar>());
|
||||
|
||||
/** @brief Reads a network model stored in <a href="https://www.tensorflow.org/">TensorFlow</a> framework's format.
|
||||
* @details This is an overloaded member function, provided for convenience.
|
||||
* It differs from the above function only in what argument(s) it accepts.
|
||||
@@ -735,6 +769,18 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
*/
|
||||
CV_EXPORTS_W Net readNet(const String& model, const String& config = "", const String& framework = "");
|
||||
|
||||
/**
|
||||
* @brief Read deep learning network represented in one of the supported formats.
|
||||
* @details This is an overloaded member function, provided for convenience.
|
||||
* It differs from the above function only in what argument(s) it accepts.
|
||||
* @param[in] framework Name of origin framework.
|
||||
* @param[in] bufferModel A buffer with a content of binary file with weights
|
||||
* @param[in] bufferConfig A buffer with a content of text file contains network configuration.
|
||||
* @returns Net object.
|
||||
*/
|
||||
CV_EXPORTS_W Net readNet(const String& framework, const std::vector<uchar>& bufferModel,
|
||||
const std::vector<uchar>& bufferConfig = std::vector<uchar>());
|
||||
|
||||
/** @brief Loads blob which was serialized as torch.Tensor object of Torch7 framework.
|
||||
* @warning This function has the same limitations as readNetFromTorch().
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package org.opencv.test.dnn;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfFloat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.dnn.DictValue;
|
||||
@@ -26,6 +30,15 @@ public class DnnTensorFlowTest extends OpenCVTestCase {
|
||||
|
||||
Net net;
|
||||
|
||||
private static void normAssert(Mat ref, Mat test) {
|
||||
final double l1 = 1e-5;
|
||||
final double lInf = 1e-4;
|
||||
double normL1 = Core.norm(ref, test, Core.NORM_L1) / ref.total();
|
||||
double normLInf = Core.norm(ref, test, Core.NORM_INF) / ref.total();
|
||||
assertTrue(normL1 < l1);
|
||||
assertTrue(normLInf < lInf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
@@ -46,7 +59,7 @@ public class DnnTensorFlowTest extends OpenCVTestCase {
|
||||
|
||||
File testDataPath = new File(envTestDataPath);
|
||||
|
||||
File f = new File(testDataPath, "dnn/space_shuttle.jpg");
|
||||
File f = new File(testDataPath, "dnn/grace_hopper_227.png");
|
||||
sourceImageFile = f.toString();
|
||||
if(!f.exists()) throw new Exception("Test image is missing: " + sourceImageFile);
|
||||
|
||||
@@ -77,31 +90,55 @@ public class DnnTensorFlowTest extends OpenCVTestCase {
|
||||
|
||||
}
|
||||
|
||||
public void testTestNetForward() {
|
||||
Mat rawImage = Imgcodecs.imread(sourceImageFile);
|
||||
public void checkInceptionNet(Net net)
|
||||
{
|
||||
Mat image = Imgcodecs.imread(sourceImageFile);
|
||||
assertNotNull("Loading image from file failed!", image);
|
||||
|
||||
assertNotNull("Loading image from file failed!", rawImage);
|
||||
|
||||
Mat image = new Mat();
|
||||
Imgproc.resize(rawImage, image, new Size(224,224));
|
||||
|
||||
Mat inputBlob = Dnn.blobFromImage(image);
|
||||
Mat inputBlob = Dnn.blobFromImage(image, 1.0, new Size(224, 224), new Scalar(0), true, true);
|
||||
assertNotNull("Converting image to blob failed!", inputBlob);
|
||||
|
||||
Mat inputBlobP = new Mat();
|
||||
Core.subtract(inputBlob, new Scalar(117.0), inputBlobP);
|
||||
|
||||
net.setInput(inputBlobP, "input" );
|
||||
|
||||
Mat result = net.forward();
|
||||
net.setInput(inputBlob, "input");
|
||||
|
||||
Mat result = new Mat();
|
||||
try {
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
result = net.forward("softmax2");
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail("DNN forward failed: " + e.getMessage());
|
||||
}
|
||||
assertNotNull("Net returned no result!", result);
|
||||
|
||||
Core.MinMaxLocResult minmax = Core.minMaxLoc(result.reshape(1, 1));
|
||||
result = result.reshape(1, 1);
|
||||
Core.MinMaxLocResult minmax = Core.minMaxLoc(result);
|
||||
assertEquals("Wrong prediction", (int)minmax.maxLoc.x, 866);
|
||||
|
||||
assertTrue("No image recognized!", minmax.maxVal > 0.9);
|
||||
Mat top5RefScores = new MatOfFloat(new float[] {
|
||||
0.63032645f, 0.2561979f, 0.032181446f, 0.015721032f, 0.014785315f
|
||||
}).reshape(1, 1);
|
||||
|
||||
Core.sort(result, result, Core.SORT_DESCENDING);
|
||||
|
||||
normAssert(result.colRange(0, 5), top5RefScores);
|
||||
}
|
||||
|
||||
public void testTestNetForward() {
|
||||
checkInceptionNet(net);
|
||||
}
|
||||
|
||||
public void testReadFromBuffer() {
|
||||
File modelFile = new File(modelFileName);
|
||||
byte[] modelBuffer = new byte[ (int)modelFile.length() ];
|
||||
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(modelFile);
|
||||
fis.read(modelBuffer);
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
fail("Failed to read a model: " + e.getMessage());
|
||||
}
|
||||
net = Dnn.readNetFromTensorflow(new MatOfByte(modelBuffer));
|
||||
checkInceptionNet(net);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,6 +453,15 @@ Net readNetFromCaffe(const char *bufferProto, size_t lenProto,
|
||||
return net;
|
||||
}
|
||||
|
||||
Net readNetFromCaffe(const std::vector<uchar>& bufferProto, const std::vector<uchar>& bufferModel)
|
||||
{
|
||||
const char* bufferProtoPtr = reinterpret_cast<const char*>(&bufferProto[0]);
|
||||
const char* bufferModelPtr = bufferModel.empty() ? NULL :
|
||||
reinterpret_cast<const char*>(&bufferModel[0]);
|
||||
return readNetFromCaffe(bufferProtoPtr, bufferProto.size(),
|
||||
bufferModelPtr, bufferModel.size());
|
||||
}
|
||||
|
||||
#endif //HAVE_PROTOBUF
|
||||
|
||||
CV__DNN_EXPERIMENTAL_NS_END
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "../precomp.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@@ -66,14 +67,19 @@ public:
|
||||
|
||||
DarknetImporter() {}
|
||||
|
||||
DarknetImporter(const char *cfgFile, const char *darknetModel)
|
||||
DarknetImporter(std::istream &cfgStream, std::istream &darknetModelStream)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
ReadNetParamsFromCfgFileOrDie(cfgFile, &net);
|
||||
ReadNetParamsFromCfgStreamOrDie(cfgStream, &net);
|
||||
ReadNetParamsFromBinaryStreamOrDie(darknetModelStream, &net);
|
||||
}
|
||||
|
||||
if (darknetModel && darknetModel[0])
|
||||
ReadNetParamsFromBinaryFileOrDie(darknetModel, &net);
|
||||
DarknetImporter(std::istream &cfgStream)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
ReadNetParamsFromCfgStreamOrDie(cfgStream, &net);
|
||||
}
|
||||
|
||||
struct BlobNote
|
||||
@@ -175,15 +181,75 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Net readNetFromDarknet(const String &cfgFile, const String &darknetModel /*= String()*/)
|
||||
static Net readNetFromDarknet(std::istream &cfgFile, std::istream &darknetModel)
|
||||
{
|
||||
DarknetImporter darknetImporter(cfgFile.c_str(), darknetModel.c_str());
|
||||
Net net;
|
||||
DarknetImporter darknetImporter(cfgFile, darknetModel);
|
||||
darknetImporter.populateNet(net);
|
||||
return net;
|
||||
}
|
||||
|
||||
static Net readNetFromDarknet(std::istream &cfgFile)
|
||||
{
|
||||
Net net;
|
||||
DarknetImporter darknetImporter(cfgFile);
|
||||
darknetImporter.populateNet(net);
|
||||
return net;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Net readNetFromDarknet(const String &cfgFile, const String &darknetModel /*= String()*/)
|
||||
{
|
||||
std::ifstream cfgStream(cfgFile.c_str());
|
||||
if (!cfgStream.is_open())
|
||||
{
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter file: " + std::string(cfgFile));
|
||||
}
|
||||
if (darknetModel != String())
|
||||
{
|
||||
std::ifstream darknetModelStream(darknetModel.c_str(), std::ios::binary);
|
||||
if (!darknetModelStream.is_open())
|
||||
{
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter file: " + std::string(darknetModel));
|
||||
}
|
||||
return readNetFromDarknet(cfgStream, darknetModelStream);
|
||||
}
|
||||
else
|
||||
return readNetFromDarknet(cfgStream);
|
||||
}
|
||||
|
||||
struct BufferStream : public std::streambuf
|
||||
{
|
||||
BufferStream(const char* s, std::size_t n)
|
||||
{
|
||||
char* ptr = const_cast<char*>(s);
|
||||
setg(ptr, ptr, ptr + n);
|
||||
}
|
||||
};
|
||||
|
||||
Net readNetFromDarknet(const char *bufferCfg, size_t lenCfg, const char *bufferModel, size_t lenModel)
|
||||
{
|
||||
BufferStream cfgBufferStream(bufferCfg, lenCfg);
|
||||
std::istream cfgStream(&cfgBufferStream);
|
||||
if (lenModel)
|
||||
{
|
||||
BufferStream weightsBufferStream(bufferModel, lenModel);
|
||||
std::istream weightsStream(&weightsBufferStream);
|
||||
return readNetFromDarknet(cfgStream, weightsStream);
|
||||
}
|
||||
else
|
||||
return readNetFromDarknet(cfgStream);
|
||||
}
|
||||
|
||||
Net readNetFromDarknet(const std::vector<uchar>& bufferCfg, const std::vector<uchar>& bufferModel)
|
||||
{
|
||||
const char* bufferCfgPtr = reinterpret_cast<const char*>(&bufferCfg[0]);
|
||||
const char* bufferModelPtr = bufferModel.empty() ? NULL :
|
||||
reinterpret_cast<const char*>(&bufferModel[0]);
|
||||
return readNetFromDarknet(bufferCfgPtr, bufferCfg.size(),
|
||||
bufferModelPtr, bufferModel.size());
|
||||
}
|
||||
|
||||
CV__DNN_EXPERIMENTAL_NS_END
|
||||
}} // namespace
|
||||
|
||||
@@ -476,68 +476,61 @@ namespace cv {
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool ReadDarknetFromCfgFile(const char *cfgFile, NetParameter *net)
|
||||
bool ReadDarknetFromCfgStream(std::istream &ifile, NetParameter *net)
|
||||
{
|
||||
std::ifstream ifile;
|
||||
ifile.open(cfgFile);
|
||||
if (ifile.is_open())
|
||||
{
|
||||
bool read_net = false;
|
||||
int layers_counter = -1;
|
||||
for (std::string line; std::getline(ifile, line);) {
|
||||
line = escapeString(line);
|
||||
if (line.empty()) continue;
|
||||
switch (line[0]) {
|
||||
case '\0': break;
|
||||
case '#': break;
|
||||
case ';': break;
|
||||
case '[':
|
||||
if (line == "[net]") {
|
||||
read_net = true;
|
||||
}
|
||||
else {
|
||||
// read section
|
||||
read_net = false;
|
||||
++layers_counter;
|
||||
const size_t layer_type_size = line.find("]") - 1;
|
||||
CV_Assert(layer_type_size < line.size());
|
||||
std::string layer_type = line.substr(1, layer_type_size);
|
||||
net->layers_cfg[layers_counter]["type"] = layer_type;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// read entry
|
||||
const size_t separator_index = line.find('=');
|
||||
CV_Assert(separator_index < line.size());
|
||||
if (separator_index != std::string::npos) {
|
||||
std::string name = line.substr(0, separator_index);
|
||||
std::string value = line.substr(separator_index + 1, line.size() - (separator_index + 1));
|
||||
name = escapeString(name);
|
||||
value = escapeString(value);
|
||||
if (name.empty() || value.empty()) continue;
|
||||
if (read_net)
|
||||
net->net_cfg[name] = value;
|
||||
else
|
||||
net->layers_cfg[layers_counter][name] = value;
|
||||
}
|
||||
bool read_net = false;
|
||||
int layers_counter = -1;
|
||||
for (std::string line; std::getline(ifile, line);) {
|
||||
line = escapeString(line);
|
||||
if (line.empty()) continue;
|
||||
switch (line[0]) {
|
||||
case '\0': break;
|
||||
case '#': break;
|
||||
case ';': break;
|
||||
case '[':
|
||||
if (line == "[net]") {
|
||||
read_net = true;
|
||||
}
|
||||
else {
|
||||
// read section
|
||||
read_net = false;
|
||||
++layers_counter;
|
||||
const size_t layer_type_size = line.find("]") - 1;
|
||||
CV_Assert(layer_type_size < line.size());
|
||||
std::string layer_type = line.substr(1, layer_type_size);
|
||||
net->layers_cfg[layers_counter]["type"] = layer_type;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// read entry
|
||||
const size_t separator_index = line.find('=');
|
||||
CV_Assert(separator_index < line.size());
|
||||
if (separator_index != std::string::npos) {
|
||||
std::string name = line.substr(0, separator_index);
|
||||
std::string value = line.substr(separator_index + 1, line.size() - (separator_index + 1));
|
||||
name = escapeString(name);
|
||||
value = escapeString(value);
|
||||
if (name.empty() || value.empty()) continue;
|
||||
if (read_net)
|
||||
net->net_cfg[name] = value;
|
||||
else
|
||||
net->layers_cfg[layers_counter][name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
std::string anchors = net->layers_cfg[net->layers_cfg.size() - 1]["anchors"];
|
||||
std::vector<float> vec = getNumbers<float>(anchors);
|
||||
std::map<std::string, std::string> &net_params = net->net_cfg;
|
||||
net->width = getParam(net_params, "width", 416);
|
||||
net->height = getParam(net_params, "height", 416);
|
||||
net->channels = getParam(net_params, "channels", 3);
|
||||
CV_Assert(net->width > 0 && net->height > 0 && net->channels > 0);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
std::string anchors = net->layers_cfg[net->layers_cfg.size() - 1]["anchors"];
|
||||
std::vector<float> vec = getNumbers<float>(anchors);
|
||||
std::map<std::string, std::string> &net_params = net->net_cfg;
|
||||
net->width = getParam(net_params, "width", 416);
|
||||
net->height = getParam(net_params, "height", 416);
|
||||
net->channels = getParam(net_params, "channels", 3);
|
||||
CV_Assert(net->width > 0 && net->height > 0 && net->channels > 0);
|
||||
|
||||
int current_channels = net->channels;
|
||||
net->out_channels_vec.resize(net->layers_cfg.size());
|
||||
|
||||
int layers_counter = -1;
|
||||
layers_counter = -1;
|
||||
|
||||
setLayersParams setParams(net);
|
||||
|
||||
@@ -676,13 +669,8 @@ namespace cv {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ReadDarknetFromWeightsFile(const char *darknetModel, NetParameter *net)
|
||||
bool ReadDarknetFromWeightsStream(std::istream &ifile, NetParameter *net)
|
||||
{
|
||||
std::ifstream ifile;
|
||||
ifile.open(darknetModel, std::ios::binary);
|
||||
CV_Assert(ifile.is_open());
|
||||
|
||||
int32_t major_ver, minor_ver, revision;
|
||||
ifile.read(reinterpret_cast<char *>(&major_ver), sizeof(int32_t));
|
||||
ifile.read(reinterpret_cast<char *>(&minor_ver), sizeof(int32_t));
|
||||
@@ -778,19 +766,18 @@ namespace cv {
|
||||
}
|
||||
|
||||
|
||||
void ReadNetParamsFromCfgFileOrDie(const char *cfgFile, darknet::NetParameter *net)
|
||||
void ReadNetParamsFromCfgStreamOrDie(std::istream &ifile, darknet::NetParameter *net)
|
||||
{
|
||||
if (!darknet::ReadDarknetFromCfgFile(cfgFile, net)) {
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter file: " + std::string(cfgFile));
|
||||
if (!darknet::ReadDarknetFromCfgStream(ifile, net)) {
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter stream");
|
||||
}
|
||||
}
|
||||
|
||||
void ReadNetParamsFromBinaryFileOrDie(const char *darknetModel, darknet::NetParameter *net)
|
||||
void ReadNetParamsFromBinaryStreamOrDie(std::istream &ifile, darknet::NetParameter *net)
|
||||
{
|
||||
if (!darknet::ReadDarknetFromWeightsFile(darknetModel, net)) {
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter file: " + std::string(darknetModel));
|
||||
if (!darknet::ReadDarknetFromWeightsStream(ifile, net)) {
|
||||
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter stream");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +109,9 @@ namespace cv {
|
||||
};
|
||||
}
|
||||
|
||||
// Read parameters from a file into a NetParameter message.
|
||||
void ReadNetParamsFromCfgFileOrDie(const char *cfgFile, darknet::NetParameter *net);
|
||||
void ReadNetParamsFromBinaryFileOrDie(const char *darknetModel, darknet::NetParameter *net);
|
||||
|
||||
// Read parameters from a stream into a NetParameter message.
|
||||
void ReadNetParamsFromCfgStreamOrDie(std::istream &ifile, darknet::NetParameter *net);
|
||||
void ReadNetParamsFromBinaryStreamOrDie(std::istream &ifile, darknet::NetParameter *net);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+58
-1
@@ -1492,7 +1492,8 @@ struct Net::Impl
|
||||
// TODO: OpenCL target support more fusion styles.
|
||||
if ( preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget) &&
|
||||
(!cv::ocl::useOpenCL() || (ld.layerInstance->type != "Convolution" &&
|
||||
ld.layerInstance->type != "MVN" && ld.layerInstance->type != "Pooling")) )
|
||||
ld.layerInstance->type != "MVN" && ld.layerInstance->type != "Pooling" &&
|
||||
ld.layerInstance->type != "Concat")) )
|
||||
continue;
|
||||
|
||||
Ptr<Layer>& currLayer = ld.layerInstance;
|
||||
@@ -1701,6 +1702,31 @@ struct Net::Impl
|
||||
ld.outputBlobs.size() == 1 )
|
||||
{
|
||||
Mat& output = ld.outputBlobs[0];
|
||||
UMat umat_output;
|
||||
if (!ld.outputBlobsWrappers.empty() &&
|
||||
(preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget)))
|
||||
{
|
||||
size_t i, ninputs = ld.inputBlobsId.size();
|
||||
bool conv_layer = true;
|
||||
for( i = 0; i < ninputs; i++ )
|
||||
{
|
||||
LayerPin pin = ld.inputBlobsId[i];
|
||||
LayerData* inp_i_data = &layers[pin.lid];
|
||||
while(inp_i_data->skip &&
|
||||
inp_i_data->inputBlobsId.size() == 1 &&
|
||||
inp_i_data->consumers.size() == 1)
|
||||
{
|
||||
pin = inp_i_data->inputBlobsId[0];
|
||||
inp_i_data = &layers[pin.lid];
|
||||
}
|
||||
conv_layer = conv_layer && (inp_i_data->getLayerInstance()->type == "Convolution");
|
||||
}
|
||||
if (!conv_layer)
|
||||
continue;
|
||||
std::vector<UMat> umat_outputBlobs;
|
||||
umat_outputBlobs = OpenCLBackendWrapper::getUMatVector(ld.outputBlobsWrappers);
|
||||
umat_output = umat_outputBlobs[0];
|
||||
}
|
||||
|
||||
// TODO: in general, this optimization can always be done, but
|
||||
// many layers currently check that the input/output blobs are
|
||||
@@ -1737,6 +1763,14 @@ struct Net::Impl
|
||||
// Allocate new memory to prevent collisions during memory
|
||||
// reusing (see https://github.com/opencv/opencv/pull/10456).
|
||||
output = output.clone();
|
||||
if (preferableBackend == DNN_BACKEND_OPENCV &&
|
||||
IS_DNN_OPENCL_TARGET(preferableTarget))
|
||||
{
|
||||
std::vector<UMat> umats(1);
|
||||
umat_output = umat_output.clone();
|
||||
umats[0] = umat_output;
|
||||
OpenCLBackendWrapper::update(ld.outputBlobsWrappers, umats);
|
||||
}
|
||||
Range chrange[] = { Range::all(), Range::all(), Range::all(), Range::all() };
|
||||
int ofs = 0;
|
||||
for( i = 0; i < ninputs; i++ )
|
||||
@@ -1753,6 +1787,12 @@ struct Net::Impl
|
||||
CV_Assert(output_slice.isContinuous() && output_slice.size == curr_output.size);
|
||||
Mat* oldPtr = &curr_output;
|
||||
curr_output = output_slice;
|
||||
if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget))
|
||||
{
|
||||
std::vector<UMat> umats(inp_i_data->outputBlobsWrappers.size());
|
||||
umats[pin.oid] = umat_output(chrange);
|
||||
OpenCLBackendWrapper::update(inp_i_data->outputBlobsWrappers, umats);
|
||||
}
|
||||
// Layers that refer old input Mat will refer to the
|
||||
// new data but the same Mat object.
|
||||
CV_Assert(curr_output.data == output_slice.data, oldPtr == &curr_output);
|
||||
@@ -3086,6 +3126,23 @@ Net readNet(const String& _model, const String& _config, const String& _framewor
|
||||
model + (config.empty() ? "" : ", " + config));
|
||||
}
|
||||
|
||||
Net readNet(const String& _framework, const std::vector<uchar>& bufferModel,
|
||||
const std::vector<uchar>& bufferConfig)
|
||||
{
|
||||
String framework = _framework.toLowerCase();
|
||||
if (framework == "caffe")
|
||||
return readNetFromCaffe(bufferConfig, bufferModel);
|
||||
else if (framework == "tensorflow")
|
||||
return readNetFromTensorflow(bufferModel, bufferConfig);
|
||||
else if (framework == "darknet")
|
||||
return readNetFromDarknet(bufferConfig, bufferModel);
|
||||
else if (framework == "torch")
|
||||
CV_Error(Error::StsNotImplemented, "Reading Torch models from buffers");
|
||||
else if (framework == "dldt")
|
||||
CV_Error(Error::StsNotImplemented, "Reading Intel's Model Optimizer models from buffers");
|
||||
CV_Error(Error::StsError, "Cannot determine an origin framework with a name " + framework);
|
||||
}
|
||||
|
||||
Net readNetFromModelOptimizer(const String &xml, const String &bin)
|
||||
{
|
||||
return Net::readFromModelOptimizer(xml, bin);
|
||||
|
||||
@@ -295,7 +295,9 @@ public:
|
||||
for (int i = 0; i < num; i++)
|
||||
confPreds.push_back(Mat(2, shape, CV_32F));
|
||||
|
||||
UMat umat = inp1.reshape(1, num * numPredsPerClass);
|
||||
shape[0] = num * numPredsPerClass;
|
||||
shape[1] = inp1.total() / shape[0];
|
||||
UMat umat = inp1.reshape(1, 2, &shape[0]);
|
||||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
Range ranges[] = { Range(i * numPredsPerClass, (i + 1) * numPredsPerClass), Range::all() };
|
||||
@@ -342,7 +344,7 @@ public:
|
||||
// Decode all loc predictions to bboxes
|
||||
bool ret = ocl_DecodeBBoxesAll(inputs[0], inputs[2], num, numPriors,
|
||||
_shareLocation, _numLocClasses, _backgroundLabelId,
|
||||
_codeType, _varianceEncodedInTarget, false,
|
||||
_codeType, _varianceEncodedInTarget, _clip,
|
||||
allDecodedBBoxes);
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
@@ -369,15 +369,11 @@ public:
|
||||
// clip the prior's coordinate such that it is within [0, 1]
|
||||
if (_clip)
|
||||
{
|
||||
Mat mat = outputs[0].getMat(ACCESS_READ);
|
||||
int aspect_count = (_maxSize > 0) ? 1 : 0;
|
||||
int offset = nthreads * 4 * _offsetsX.size() * (1 + aspect_count + _aspectRatios.size());
|
||||
float* outputPtr = mat.ptr<float>() + offset;
|
||||
int _outChannelSize = _layerHeight * _layerWidth * _numPriors * 4;
|
||||
for (size_t d = 0; d < _outChannelSize; ++d)
|
||||
{
|
||||
outputPtr[d] = std::min<float>(std::max<float>(outputPtr[d], 0.), 1.);
|
||||
}
|
||||
ocl::Kernel kernel("clip", ocl::dnn::prior_box_oclsrc, opts);
|
||||
size_t nthreads = _layerHeight * _layerWidth * _numPriors * 4;
|
||||
if (!kernel.args((int)nthreads, ocl::KernelArg::PtrReadWrite(outputs[0]))
|
||||
.run(1, &nthreads, NULL, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the variance.
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace cv { namespace dnn {
|
||||
class ResizeLayerImpl : public ResizeLayer
|
||||
{
|
||||
public:
|
||||
ResizeLayerImpl(const LayerParams& params)
|
||||
ResizeLayerImpl(const LayerParams& params) : scaleWidth(0), scaleHeight(0)
|
||||
{
|
||||
setParamsFrom(params);
|
||||
outWidth = params.get<float>("width", 0);
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
ShuffleChannelLayerImpl(const LayerParams& params)
|
||||
{
|
||||
group = params.get<int>("group", 1);
|
||||
setParamsFrom(params);
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
||||
@@ -110,27 +110,26 @@ public:
|
||||
outputs_.getUMatVector(outputs);
|
||||
internals_.getUMatVector(internals);
|
||||
|
||||
UMat& src = inputs[0];
|
||||
UMat& dstMat = outputs[0];
|
||||
int axis = clamp(axisRaw, src.dims);
|
||||
|
||||
if (softmaxOp.empty())
|
||||
{
|
||||
OCL4DNNSoftmaxConfig config;
|
||||
|
||||
config.in_shape = shape(inputs[0]);
|
||||
config.axis = axisRaw;
|
||||
config.channels = inputs[0].size[axisRaw];
|
||||
config.axis = axis;
|
||||
config.channels = inputs[0].size[axis];
|
||||
config.logsoftmax = logSoftMax;
|
||||
config.use_half = use_half;
|
||||
|
||||
softmaxOp = Ptr<OCL4DNNSoftmax<float> >(new OCL4DNNSoftmax<float>(config));
|
||||
}
|
||||
|
||||
UMat& src = inputs[0];
|
||||
UMat& dstMat = outputs[0];
|
||||
|
||||
if (softmaxOp->Forward(src, dstMat))
|
||||
return true;
|
||||
|
||||
UMat& bufMat = internals[0];
|
||||
int axis = clamp(axisRaw, src.dims);
|
||||
MatShape s = shape(src);
|
||||
size_t outerSize = total(s, 0, axis);
|
||||
size_t channels = src.size[axis];
|
||||
|
||||
@@ -612,7 +612,7 @@ bool ocl4dnnGEMV<float>(const CBLAS_TRANSPOSE TransA,
|
||||
ret = k.run(1, globalsize, localsize, false);
|
||||
}
|
||||
|
||||
if ((row_size % 4) != 0 && ret)
|
||||
if (row_size < 4 || ((row_size % 4) != 0 && ret))
|
||||
{
|
||||
String kname = format("matvec_mul1_%s", use_half ? "half" : "float");
|
||||
ocl::Kernel k_1(kname.c_str(), cv::ocl::dnn::matvec_mul_oclsrc, opts);
|
||||
|
||||
@@ -821,7 +821,7 @@ void OCL4DNNConvSpatial<float>::CreateSubBuffer(const UMat& buffer, UMat& sub_bu
|
||||
cl_int err;
|
||||
size_t element_size = (use_half_) ? sizeof(short) : sizeof(float);
|
||||
|
||||
region.origin = offset * element_size;
|
||||
region.origin = offset * element_size + buffer.offset;
|
||||
region.size = size * element_size;
|
||||
sub_mem = clCreateSubBuffer((cl_mem)buffer.handle(ACCESS_READ),
|
||||
write_only ? CL_MEM_WRITE_ONLY : CL_MEM_READ_ONLY,
|
||||
@@ -853,6 +853,7 @@ bool OCL4DNNConvSpatial<float>::convolve(const UMat &bottom, UMat &top,
|
||||
return false;
|
||||
|
||||
int32_t bias_offset;
|
||||
int32_t element_size = use_half_ ? sizeof(short) : sizeof(float);
|
||||
|
||||
if (config->kernelType == KERNEL_TYPE_INTEL_IDLF) {
|
||||
if (!swizzleWeight(weight, config->workItem_output[2], false))
|
||||
@@ -931,10 +932,12 @@ bool OCL4DNNConvSpatial<float>::convolve(const UMat &bottom, UMat &top,
|
||||
return false;
|
||||
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(out_buffer));
|
||||
kernel.set(argIdx++, (int)(out_buffer.offset / element_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(top));
|
||||
kernel.set(argIdx++, (int)(top.offset / element_size));
|
||||
}
|
||||
|
||||
kernel.set(argIdx++, (uint16_t)width_);
|
||||
@@ -1024,10 +1027,12 @@ bool OCL4DNNConvSpatial<float>::convolve(const UMat &bottom, UMat &top,
|
||||
return false;
|
||||
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(out_buffer));
|
||||
kernel.set(argIdx++, (int)(out_buffer.offset / element_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(top));
|
||||
kernel.set(argIdx++, (int)(top.offset / element_size));
|
||||
}
|
||||
|
||||
kernel.set(argIdx++, (uint16_t)width_);
|
||||
@@ -1079,6 +1084,7 @@ bool OCL4DNNConvSpatial<float>::convolve(const UMat &bottom, UMat &top,
|
||||
if (bias_term_)
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrReadOnly(bias));
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(top));
|
||||
kernel.set(argIdx++, (int)(top.offset / element_size));
|
||||
kernel.set(argIdx++, (uint16_t)width_);
|
||||
kernel.set(argIdx++, (uint16_t)height_);
|
||||
kernel.set(argIdx++, (uint16_t)output_w_);
|
||||
@@ -1126,6 +1132,7 @@ bool OCL4DNNConvSpatial<float>::convolve(const UMat &bottom, UMat &top,
|
||||
kernel.set(argIdx++, (void *)NULL);
|
||||
kernel.set(argIdx++, bias_offset);
|
||||
kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(top));
|
||||
kernel.set(argIdx++, (int)(top.offset / element_size));
|
||||
kernel.set(argIdx++, output_image_offset);
|
||||
kernel.set(argIdx++, (uint16_t)width_);
|
||||
kernel.set(argIdx++, (uint16_t)height_);
|
||||
@@ -1230,20 +1237,22 @@ bool OCL4DNNConvSpatial<float>::verifyResult(const UMat &bottom,
|
||||
tuned_ = saved_tuned;
|
||||
|
||||
UMat new_top, new_verify_top;
|
||||
float *data, *verify_data;
|
||||
Mat mat_top, mat_verify_top;
|
||||
if (use_half_)
|
||||
{
|
||||
convertFp16(top, new_top);
|
||||
convertFp16(verifyTop, new_verify_top);
|
||||
|
||||
data = (float *)new_top.getMat(ACCESS_READ).ptr<float>();
|
||||
verify_data = (float *)new_verify_top.getMat(ACCESS_READ).ptr<float>();
|
||||
mat_top = new_top.getMat(ACCESS_READ);
|
||||
mat_verify_top = new_verify_top.getMat(ACCESS_READ);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (float *)top.getMat(ACCESS_READ).ptr<float>();
|
||||
verify_data = (float *)verifyTop.getMat(ACCESS_READ).ptr<float>();
|
||||
mat_top = top.getMat(ACCESS_READ);
|
||||
mat_verify_top = verifyTop.getMat(ACCESS_READ);
|
||||
}
|
||||
const float* data = mat_top.ptr<float>();
|
||||
const float* verify_data = mat_verify_top.ptr<float>();
|
||||
|
||||
for (int32_t n = 0; n < num_; ++n) {
|
||||
for (int32_t g = 0; g < group_; ++g) {
|
||||
|
||||
@@ -136,7 +136,8 @@ __kernel void ConvolveBasic(
|
||||
int kernel_offset,
|
||||
__global Dtype* bias,
|
||||
const int bias_offset,
|
||||
__global Dtype* convolved_image,
|
||||
__global Dtype* convolved_image_base,
|
||||
const int convolved_image_base_offset,
|
||||
const int convolved_image_offset,
|
||||
const ushort input_width,
|
||||
const ushort input_height,
|
||||
@@ -146,6 +147,7 @@ __kernel void ConvolveBasic(
|
||||
const ushort pad_h
|
||||
)
|
||||
{
|
||||
__global Dtype* convolved_image = convolved_image_base + convolved_image_base_offset;
|
||||
const int outputX = get_global_id(0);
|
||||
const int outputY = get_global_id(1);
|
||||
const int kernelNum = get_global_id(2) * ZPAR;
|
||||
@@ -220,12 +222,14 @@ convolve_simd(
|
||||
__global Dtype* inputs,
|
||||
__global Dtype* weights,
|
||||
BIAS_KERNEL_ARG
|
||||
__global Dtype* outputs,
|
||||
__global Dtype* outputs_base,
|
||||
const int outputs_offset,
|
||||
const ushort input_width,
|
||||
const ushort input_height,
|
||||
const ushort output_width,
|
||||
const ushort output_height)
|
||||
{
|
||||
__global Dtype* outputs = outputs_base + outputs_offset;
|
||||
unsigned int oc = get_global_id(0) * OUT_BLOCK_WIDTH; // oc = Output Column
|
||||
unsigned int or = get_global_id(1) * OUT_BLOCK_HEIGHT; // or = Output Row
|
||||
unsigned int fm = get_global_id(2); // fm = Feature Map = od = Output Depth
|
||||
@@ -395,7 +399,8 @@ typedef struct half0 { half s0; } half0; //never used but makes compiler happy.
|
||||
const __global Dtype *src0, \
|
||||
const __global Dtype *src1, \
|
||||
BIAS_KERNEL_ARG \
|
||||
__global Dtype *dst, \
|
||||
__global Dtype *dst_base, \
|
||||
const int dst_offset, \
|
||||
const ushort input_width, \
|
||||
const ushort input_height, \
|
||||
const ushort output_width, \
|
||||
@@ -425,6 +430,7 @@ typedef struct half0 { half s0; } half0; //never used but makes compiler happy.
|
||||
__attribute__((intel_reqd_sub_group_size(8)))
|
||||
__kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
{
|
||||
__global Dtype *dst = dst_base + dst_offset;
|
||||
const int group_x = get_group_id(0);
|
||||
const int group_y = get_group_id(1);
|
||||
const int global_x = get_global_id(0);
|
||||
@@ -813,6 +819,7 @@ __kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
__attribute__((intel_reqd_sub_group_size(8)))
|
||||
__kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
{
|
||||
__global Dtype *dst = dst_base + dst_offset;
|
||||
const int group_x = get_group_id(0);
|
||||
const int group_y = get_group_id(1);
|
||||
const int global_x = get_global_id(0);
|
||||
@@ -1374,6 +1381,7 @@ __kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
__attribute__((intel_reqd_sub_group_size(16)))
|
||||
__kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
{
|
||||
__global Dtype *dst = dst_base + dst_offset;
|
||||
const int group_x = get_group_id(0);
|
||||
const int group_y = get_group_id(1);
|
||||
const int global_x = get_global_id(0);
|
||||
@@ -1559,6 +1567,7 @@ __kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
__attribute__((intel_reqd_sub_group_size(16)))
|
||||
__kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
|
||||
{
|
||||
__global Dtype *dst = dst_base + dst_offset;
|
||||
const int group_x = get_group_id(0);
|
||||
const int group_y = get_group_id(1);
|
||||
const int global_x = get_global_id(0);
|
||||
@@ -1770,12 +1779,13 @@ __kernel void DWCONV(
|
||||
__global Dtype* image_data,
|
||||
__global Dtype* kernel_data,
|
||||
BIAS_KERNEL_ARG
|
||||
__global Dtype* convolved_image,
|
||||
__global Dtype* convolved_image_base,
|
||||
const int convolved_image_offset,
|
||||
const ushort input_width,
|
||||
const ushort input_height,
|
||||
const ushort output_width,
|
||||
const ushort output_height) {
|
||||
|
||||
__global Dtype* convolved_image = convolved_image_base + convolved_image_offset;
|
||||
const int outputX = get_global_id(0);
|
||||
const int outputY = get_global_id(1);
|
||||
const int outputZ = get_global_id(2);
|
||||
|
||||
@@ -107,3 +107,13 @@ __kernel void set_variance(const int nthreads,
|
||||
vstore4(var_vec, 0, dst + offset + index * 4);
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void clip(const int nthreads,
|
||||
__global Dtype* dst)
|
||||
{
|
||||
for (int index = get_global_id(0); index < nthreads; index += get_global_size(0))
|
||||
{
|
||||
Dtype4 vec = vload4(index, dst);
|
||||
vstore4(clamp(vec, 0, 1), index, dst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1856,5 +1856,14 @@ Net readNetFromTensorflow(const char* bufferModel, size_t lenModel,
|
||||
return net;
|
||||
}
|
||||
|
||||
Net readNetFromTensorflow(const std::vector<uchar>& bufferModel, const std::vector<uchar>& bufferConfig)
|
||||
{
|
||||
const char* bufferModelPtr = reinterpret_cast<const char*>(&bufferModel[0]);
|
||||
const char* bufferConfigPtr = bufferConfig.empty() ? NULL :
|
||||
reinterpret_cast<const char*>(&bufferConfig[0]);
|
||||
return readNetFromTensorflow(bufferModelPtr, bufferModel.size(),
|
||||
bufferConfigPtr, bufferConfig.size());
|
||||
}
|
||||
|
||||
CV__DNN_EXPERIMENTAL_NS_END
|
||||
}} // namespace
|
||||
|
||||
@@ -65,6 +65,34 @@ TEST(Test_Darknet, read_yolo_voc)
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_yolo_voc_stream)
|
||||
{
|
||||
Mat ref;
|
||||
Mat sample = imread(_tf("dog416.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0/255, Size(416, 416), Scalar(), true, false);
|
||||
const std::string cfgFile = findDataFile("dnn/yolo-voc.cfg", false);
|
||||
const std::string weightsFile = findDataFile("dnn/yolo-voc.weights", false);
|
||||
// Import by paths.
|
||||
{
|
||||
Net net = readNetFromDarknet(cfgFile, weightsFile);
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
ref = net.forward();
|
||||
}
|
||||
// Import from bytes array.
|
||||
{
|
||||
std::string cfg, weights;
|
||||
readFileInMemory(cfgFile, cfg);
|
||||
readFileInMemory(weightsFile, weights);
|
||||
|
||||
Net net = readNetFromDarknet(&cfg[0], cfg.size(), &weights[0], weights.size());
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
Mat out = net.forward();
|
||||
normAssert(ref, out);
|
||||
}
|
||||
}
|
||||
|
||||
class Test_Darknet_layers : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -104,8 +104,14 @@ TEST_P(Convolution, Accuracy)
|
||||
int backendId = get<0>(get<7>(GetParam()));
|
||||
int targetId = get<1>(get<7>(GetParam()));
|
||||
|
||||
if ((backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD) ||
|
||||
(backendId == DNN_BACKEND_OPENCV && targetId == DNN_TARGET_OPENCL_FP16))
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
|
||||
// TODO: unstable test cases
|
||||
if (backendId == DNN_BACKEND_OPENCV && (targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16) &&
|
||||
inChannels == 6 && outChannels == 9 && group == 1 && inSize == Size(5, 6) &&
|
||||
kernel == Size(3, 1) && stride == Size(1, 1) && pad == Size(0, 1) && dilation == Size(1, 1) &&
|
||||
hasBias)
|
||||
throw SkipTestException("");
|
||||
|
||||
int sz[] = {outChannels, inChannels / group, kernel.height, kernel.width};
|
||||
@@ -353,8 +359,7 @@ TEST_P(FullyConnected, Accuracy)
|
||||
bool hasBias = get<3>(GetParam());
|
||||
int backendId = get<0>(get<4>(GetParam()));
|
||||
int targetId = get<1>(get<4>(GetParam()));
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE ||
|
||||
(backendId == DNN_BACKEND_OPENCV && targetId == DNN_TARGET_OPENCL_FP16))
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("");
|
||||
|
||||
Mat weights(outChannels, inChannels * inSize.height * inSize.width, CV_32F);
|
||||
@@ -692,10 +697,6 @@ TEST_P(Eltwise, Accuracy)
|
||||
int backendId = get<0>(get<4>(GetParam()));
|
||||
int targetId = get<1>(get<4>(GetParam()));
|
||||
|
||||
if (backendId == DNN_BACKEND_OPENCV &&
|
||||
(targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
|
||||
Net net;
|
||||
|
||||
std::vector<int> convLayerIds(numConv);
|
||||
|
||||
@@ -763,8 +763,7 @@ TEST_P(Test_Caffe_layers, Average_pooling_kernel_area)
|
||||
// Test PriorBoxLayer in case of no aspect ratios (just squared proposals).
|
||||
TEST_P(Test_Caffe_layers, PriorBox_squares)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE ||
|
||||
(backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)))
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("");
|
||||
LayerParams lp;
|
||||
lp.name = "testPriorBox";
|
||||
@@ -791,7 +790,8 @@ TEST_P(Test_Caffe_layers, PriorBox_squares)
|
||||
0.25, 0.0, 1.0, 1.0,
|
||||
0.1f, 0.1f, 0.2f, 0.2f,
|
||||
0.1f, 0.1f, 0.2f, 0.2f);
|
||||
normAssert(out.reshape(1, 4), ref);
|
||||
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 2e-5 : 1e-5;
|
||||
normAssert(out.reshape(1, 4), ref, "", l1);
|
||||
}
|
||||
|
||||
typedef TestWithParam<tuple<int, int> > Layer_Test_DWconv_Prelu;
|
||||
|
||||
@@ -243,10 +243,15 @@ TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
|
||||
runTensorFlowNet("l2_normalize_3d");
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<Target> Test_TensorFlow_nets;
|
||||
class Test_TensorFlow_nets : public DNNTestLayer {};
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
|
||||
{
|
||||
checkBackend();
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
|
||||
std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
|
||||
std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt", false);
|
||||
std::string imgPath = findDataFile("dnn/street.png", false);
|
||||
@@ -260,29 +265,30 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
|
||||
outNames[1] = "concat_1";
|
||||
outNames[2] = "detection_out";
|
||||
|
||||
std::vector<Mat> target(outNames.size());
|
||||
std::vector<Mat> refs(outNames.size());
|
||||
for (int i = 0; i < outNames.size(); ++i)
|
||||
{
|
||||
std::string path = findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco." + outNames[i] + ".npy", false);
|
||||
target[i] = blobFromNPY(path);
|
||||
refs[i] = blobFromNPY(path);
|
||||
}
|
||||
|
||||
Net net = readNetFromTensorflow(netPath, netConfig);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(GetParam());
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
net.setInput(inp);
|
||||
|
||||
std::vector<Mat> output;
|
||||
net.forward(output, outNames);
|
||||
|
||||
normAssert(target[0].reshape(1, 1), output[0].reshape(1, 1), "", 1e-5, 1.5e-4);
|
||||
normAssert(target[1].reshape(1, 1), output[1].reshape(1, 1), "", 1e-5, 3e-4);
|
||||
normAssertDetections(target[2], output[2], "", 0.2);
|
||||
normAssert(refs[0].reshape(1, 1), output[0].reshape(1, 1), "", 1e-5, 1.5e-4);
|
||||
normAssert(refs[1].reshape(1, 1), output[1].reshape(1, 1), "", 1e-5, 3e-4);
|
||||
normAssertDetections(refs[2], output[2], "", 0.2);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
{
|
||||
checkBackend();
|
||||
std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt", false);
|
||||
std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
|
||||
|
||||
@@ -290,8 +296,8 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
Mat img = imread(findDataFile("dnn/street.png", false));
|
||||
Mat blob = blobFromImage(img, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), true, false);
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(GetParam());
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
net.setInput(blob);
|
||||
// Output has shape 1x1xNx7 where N - number of detections.
|
||||
@@ -302,16 +308,24 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
|
||||
0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
|
||||
0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
|
||||
normAssertDetections(ref, out, "", 0.5);
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 5e-3 : default_l1;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.025 : default_lInf;
|
||||
normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, Inception_v2_Faster_RCNN)
|
||||
{
|
||||
checkBackend();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
|
||||
std::string proto = findDataFile("dnn/faster_rcnn_inception_v2_coco_2018_01_28.pbtxt", false);
|
||||
std::string model = findDataFile("dnn/faster_rcnn_inception_v2_coco_2018_01_28.pb", false);
|
||||
|
||||
Net net = readNetFromTensorflow(model, proto);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
Mat img = imread(findDataFile("dnn/dog416.png", false));
|
||||
Mat blob = blobFromImage(img, 1.0f / 127.5, Size(800, 600), Scalar(127.5, 127.5, 127.5), true, false);
|
||||
|
||||
@@ -324,6 +338,11 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_Faster_RCNN)
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
{
|
||||
checkBackend();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
|
||||
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
|
||||
std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt", false);
|
||||
std::string model = findDataFile("dnn/opencv_face_detector_uint8.pb", false);
|
||||
|
||||
@@ -331,9 +350,8 @@ TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
Mat img = imread(findDataFile("gpu/lbpcascade/er.png", false));
|
||||
Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(GetParam());
|
||||
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.setInput(blob);
|
||||
// Output has shape 1x1xNx7 where N - number of detections.
|
||||
// An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
|
||||
@@ -346,7 +364,9 @@ TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
|
||||
0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
|
||||
0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
|
||||
normAssertDetections(ref, out, "", 0.9, 3.4e-3, 1e-2);
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 4e-3 : 3.4e-3;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : 1e-2;
|
||||
normAssertDetections(ref, out, "", 0.9, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
// inp = cv.imread('opencv_extra/testdata/cv/ximgproc/sources/08.png')
|
||||
@@ -360,6 +380,10 @@ TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
// np.save('east_text_detection.geometry.npy', geometry)
|
||||
TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
{
|
||||
checkBackend();
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
|
||||
std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
|
||||
std::string imgPath = findDataFile("cv/ximgproc/sources/08.png", false);
|
||||
std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy", false);
|
||||
@@ -367,7 +391,8 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
|
||||
Net net = readNet(findDataFile("dnn/frozen_east_text_detection.pb", false));
|
||||
|
||||
net.setPreferableTarget(GetParam());
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
Mat img = imread(imgPath);
|
||||
Mat inp = blobFromImage(img, 1.0, Size(), Scalar(123.68, 116.78, 103.94), true, false);
|
||||
@@ -386,7 +411,7 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
normAssert(geometry, blobFromNPY(refGeometryPath), "geometry", 1e-4, 3e-3);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, availableDnnTargets());
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, fp16_weights)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user