#include #include #include #include #include const char* keys = "{ help h | | Print help message. }" "{ input i | | Path to input image or video file. Skip this argument to capture frames from a camera.}" "{ model m | | Path to a binary file of model contains trained weights. " "It could be a file with extensions .caffemodel (Caffe), " ".pb (TensorFlow), .t7 or .net (Torch), .weights (Darknet) }" "{ config c | | Path to a text file of model contains network configuration. " "It could be a file with extensions .prototxt (Caffe), .pbtxt (TensorFlow), .cfg (Darknet) }" "{ framework f | | Optional name of an origin framework of the model. Detect it automatically if it does not set. }" "{ classes | | Optional path to a text file with names of classes. }" "{ mean | | Preprocess input image by subtracting mean values. Mean values should be in BGR order and delimited by spaces. }" "{ scale | 1 | Preprocess input image by multiplying on a scale factor. }" "{ width | | Preprocess input image by resizing to a specific width. }" "{ height | | Preprocess input image by resizing to a specific height. }" "{ rgb | | Indicate that model works with RGB input images instead BGR ones. }" "{ backend | 0 | Choose one of computation backends: " "0: default C++ backend, " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)}" "{ target | 0 | Choose one of target computation devices: " "0: CPU target (by default)," "1: OpenCL }"; using namespace cv; using namespace dnn; std::vector classes; int main(int argc, char** argv) { CommandLineParser parser(argc, argv, keys); parser.about("Use this script to run classification deep learning networks using OpenCV."); if (argc == 1 || parser.has("help")) { parser.printMessage(); return 0; } float scale = parser.get("scale"); Scalar mean = parser.get("mean"); bool swapRB = parser.get("rgb"); CV_Assert(parser.has("width"), parser.has("height")); int inpWidth = parser.get("width"); int inpHeight = parser.get("height"); String model = parser.get("model"); String config = parser.get("config"); String framework = parser.get("framework"); int backendId = parser.get("backend"); int targetId = parser.get("target"); // Open file with classes names. if (parser.has("classes")) { std::string file = parser.get("classes"); std::ifstream ifs(file.c_str()); if (!ifs.is_open()) CV_Error(Error::StsError, "File " + file + " not found"); std::string line; while (std::getline(ifs, line)) { classes.push_back(line); } } CV_Assert(parser.has("model")); //! [Read and initialize network] Net net = readNet(model, config, framework); net.setPreferableBackend(backendId); net.setPreferableTarget(targetId); //! [Read and initialize network] // Create a window static const std::string kWinName = "Deep learning image classification in OpenCV"; namedWindow(kWinName, WINDOW_NORMAL); //! [Open a video file or an image file or a camera stream] VideoCapture cap; if (parser.has("input")) cap.open(parser.get("input")); else cap.open(0); //! [Open a video file or an image file or a camera stream] // Process frames. Mat frame, blob; while (waitKey(1) < 0) { cap >> frame; if (frame.empty()) { waitKey(); break; } //! [Create a 4D blob from a frame] blobFromImage(frame, blob, scale, Size(inpWidth, inpHeight), mean, swapRB, false); //! [Create a 4D blob from a frame] //! [Set input blob] net.setInput(blob); //! [Set input blob] //! [Make forward pass] Mat prob = net.forward(); //! [Make forward pass] //! [Get a class with a highest score] Point classIdPoint; double confidence; minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint); int classId = classIdPoint.x; //! [Get a class with a highest score] // Put efficiency information. std::vector layersTimes; double freq = getTickFrequency() / 1000; double t = net.getPerfProfile(layersTimes) / freq; std::string label = format("Inference time: %.2f ms", t); putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); // Print predicted class. label = format("%s: %.4f", (classes.empty() ? format("Class #%d", classId).c_str() : classes[classId].c_str()), confidence); putText(frame, label, Point(0, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); imshow(kWinName, frame); } return 0; }