*/
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 cfgFile file node to the .cfg file with text description of the network architecture.
- * @param darknetModel file node to the .weights file with learned network.
- * @returns Network object that ready to do forward, throw an exception in failure cases.
- * @returns Net object.
- */
- CV_EXPORTS_W Net readNetFromDarknet(const FileNode &cfgFile, const FileNode &darknetModel = FileNode());
+ /** @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<char>& bufferCfg,
+ const std::vector<char>& bufferModel = std::vector<char>());
+
+ /** @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.
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<char>& bufferProto,
+ const std::vector<char>& bufferModel = std::vector<char>());
+
+ /** @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.
* @param bufferProto buffer containing the content of the .prototxt file
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<char>& bufferModel,
+ const std::vector<char>& bufferConfig = std::vector<char>());
+
+ /** @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.
* @param bufferModel buffer containing the content of the pb file
*/
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<char>& bufferModel,
+ const std::vector<char>& bufferConfig = std::vector<char>());
+
/** @brief Loads blob which was serialized as torch.Tensor object of Torch7 framework.
* @warning This function has the same limitations as readNetFromTorch().
*/
return net;
}
+Net readNetFromCaffe(const std::vector<char>& bufferProto, const std::vector<char>& bufferModel)
+{
+ return readNetFromCaffe(&bufferProto[0], bufferProto.size(),
+ bufferModel.empty() ? NULL : &bufferModel[0], bufferModel.size());
+}
+
#endif //HAVE_PROTOBUF
CV__DNN_EXPERIMENTAL_NS_END
}
};
+static Net readNetFromDarknet(std::istream &cfgFile, std::istream &darknetModel)
+{
+ Net net;
+ DarknetImporter darknetImporter(cfgFile, darknetModel);
+ darknetImporter.populateNet(net);
+ return net;
}
-Net readNetFromDarknet(const String &cfgFile, const String &darknetModel /*= String()*/)
+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()) {
+ if (!cfgStream.is_open())
+ {
CV_Error(cv::Error::StsParseError, "Failed to parse NetParameter file: " + std::string(cfgFile));
- return net;
}
- DarknetImporter darknetImporter;
- if (darknetModel != String()) {
- std::ifstream darknetModelStream(darknetModel.c_str());
- if(!darknetModelStream.is_open()){
+ 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 net;
}
- darknetImporter = DarknetImporter(cfgStream, darknetModelStream);
- } else {
- darknetImporter = DarknetImporter(cfgStream);
+ return readNetFromDarknet(cfgStream, darknetModelStream);
}
- darknetImporter.populateNet(net);
- return net;
+ else
+ return readNetFromDarknet(cfgStream);
}
-Net readNetFromDarknet(const FileNode &cfgFile, const FileNode &darknetModel /*= FileNode()*/)
+struct BufferStream : public std::streambuf
{
- DarknetImporter darknetImporter;
- if(darknetModel.empty()){
- std::istringstream cfgStream((std::string)cfgFile);
- darknetImporter = DarknetImporter(cfgStream);
- }else{
- std::istringstream cfgStream((std::string)cfgFile);
- std::istringstream darknetModelStream((std::string)darknetModel);
- darknetImporter = DarknetImporter(cfgStream, darknetModelStream);
+ BufferStream(const char* s, std::size_t n)
+ {
+ char* ptr = const_cast<char*>(s);
+ setg(ptr, ptr, ptr + n);
}
- Net net;
- darknetImporter.populateNet(net);
- return net;
+};
+
+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<char>& bufferCfg, const std::vector<char>& bufferModel)
+{
+ return readNetFromDarknet(&bufferCfg[0], bufferCfg.size(),
+ bufferModel.empty() ? NULL : &bufferModel[0], bufferModel.size());
}
CV__DNN_EXPERIMENTAL_NS_END
model + (config.empty() ? "" : ", " + config));
}
+Net readNet(const String& _framework, const std::vector<char>& bufferModel,
+ const std::vector<char>& 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);
return net;
}
+Net readNetFromTensorflow(const std::vector<char>& bufferModel, const std::vector<char>& bufferConfig)
+{
+ return readNetFromCaffe(&bufferModel[0], bufferModel.size(),
+ bufferConfig.empty() ? NULL : &bufferConfig[0], bufferConfig.size());
+}
+
CV__DNN_EXPERIMENTAL_NS_END
}} // namespace
ASSERT_FALSE(net.empty());
}
-TEST(Test_Darknet, read_filestorage_yolo_voc)
+TEST(Test_Darknet, read_yolo_voc_stream)
{
- std::ifstream ifile(_tf("yolo-voc.cfg").c_str());
- std::stringstream buffer;
- buffer << " " << ifile.rdbuf(); // FIXME: FileStorage drops first character.
- FileStorage ofs(".xml", FileStorage::WRITE | FileStorage::MEMORY);
- ofs.write("cfgFile", buffer.str());
- FileStorage ifs(ofs.releaseAndGetString(), FileStorage::READ | FileStorage::MEMORY | FileStorage::FORMAT_XML);
- Net net = readNetFromDarknet(ifs["cfgFile"]);
- ASSERT_FALSE(net.empty());
+ 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