Skip to content
29 changes: 29 additions & 0 deletions models/image_classification_mobilenet/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.2)
set(project_name "opencv_zoo_image_classification_mobilenet")

PROJECT (${project_name})

set(OPENCV_VERSION "4.7.0")
set(OPENCV_INSTALLATION_PATH "" CACHE PATH "Where to look for OpenCV installation")
find_package(OpenCV ${OPENCV_VERSION} REQUIRED HINTS ${OPENCV_INSTALLATION_PATH})
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI

file(GLOB SourceFile
"demo.cpp")
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " config: ${OpenCV_DIR}")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")

# Declare the executable target built from your sources
add_executable(${project_name} ${SourceFile})

# Link your application with OpenCV libraries
target_link_libraries(${project_name} PRIVATE ${OpenCV_LIBS})
20 changes: 20 additions & 0 deletions models/image_classification_mobilenet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Results of accuracy evaluation with [tools/eval](../../tools/eval).

## Demo

### Python

Run the following command to try the demo:

```shell
Expand All @@ -29,6 +31,24 @@ python demo.py --input /path/to/image --model v2
python demo.py --help
```

### C++

Install latest OpenCV and CMake >= 3.24.0 to get started with:

```shell
# A typical and default installation path of OpenCV is /usr/local
cmake -B build -D OPENCV_INSTALLATION_PATH=/path/to/opencv/installation .
cmake --build build

# detect on camera input
./build/opencv_zoo_image_classification_mobilenet
# detect on an image
./build/opencv_zoo_image_classification_mobilenet -m=/path/to/model -i=/path/to/image -v
# get help messages
./build/opencv_zoo_image_classification_mobilenet -h
```


## License

All files in this directory are licensed under [Apache 2.0 License](./LICENSE).
Expand Down
117 changes: 117 additions & 0 deletions models/image_classification_mobilenet/demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include <vector>
#include <string>
#include <utility>

#include <opencv2/opencv.hpp>
#include "labelsimagenet1k.h"

using namespace std;
using namespace cv;
using namespace dnn;

vector< pair<dnn::Backend, dnn::Target> > backendTargetPairs = {
std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_OPENCV, dnn::DNN_TARGET_CPU),
std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_CUDA, dnn::DNN_TARGET_CUDA),
std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_CUDA, dnn::DNN_TARGET_CUDA_FP16),
std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_TIMVX, dnn::DNN_TARGET_NPU),
std::make_pair<dnn::Backend, dnn::Target>(dnn::DNN_BACKEND_CANN, dnn::DNN_TARGET_NPU) };


std::string keys =
"{ help h | | Print help message. }"
"{ model m | image_classification_mobilenetv1_2022apr.onnx | Usage: Set model type, defaults to image_classification_mobilenetv1_2022apr.onnx (v1) }"
"{ input i | | Path to input image or video file. Skip this argument to capture frames from a camera.}"
"{ initial_width | 0 | Preprocess input image by initial resizing to a specific width.}"
"{ initial_height | 0 | Preprocess input image by initial resizing to a specific height.}"
"{ rgb | true | swap R and B plane.}"
"{ crop | false | Preprocess input image by center cropping.}"
"{ backend bt | 0 | Choose one of computation backends: "
"0: (default) OpenCV implementation + CPU, "
"1: CUDA + GPU (CUDA), "
"2: CUDA + GPU (CUDA FP16), "
"3: TIM-VX + NPU, "
"4: CANN + NPU}";


int main(int argc, char** argv)
{
CommandLineParser parser(argc, argv, keys);

parser.about("Use this script to run classification deep learning networks in opencv Zoo using OpenCV.");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}

int rszWidth = parser.get<int>("initial_width");
int rszHeight = parser.get<int>("initial_height");
bool swapRB = parser.get<bool>("rgb");
bool crop = parser.get<bool>("crop");
String model = parser.get<String>("model");
int backendTargetid = parser.get<int>("backend");

if (model.empty())
{
CV_Error(Error::StsError, "Model file " + model + " not found");
}
vector<string> labels = getLabelsImagenet1k();

Net net = readNet(model);
net.setPreferableBackend(backendTargetPairs[backendTargetid].first);
net.setPreferableTarget(backendTargetPairs[backendTargetid].second);
//! [Open a video file or an image file or a camera stream]
VideoCapture cap;
if (parser.has("input"))
cap.open(parser.get<String>("input"));
else
cap.open(0);
if (!cap.isOpened())
CV_Error(Error::StsError, "Cannot opend video or file");
Mat frame, blob;
static const std::string kWinName = model;
while (waitKey(1) < 0)
{
cap >> frame;
if (frame.empty())
{
cout << "Frame is empty" << endl;
waitKey();
break;
}

if (rszWidth != 0 && rszHeight != 0)
{
resize(frame, frame, Size(rszWidth, rszHeight));
}
Image2BlobParams paramMobilenet;
paramMobilenet.datalayout = DNN_LAYOUT_NCHW;
paramMobilenet.ddepth = CV_32F;
paramMobilenet.mean = Scalar(123.675, 116.28, 103.53);
paramMobilenet.scalefactor = Scalar(1 / (255. * 0.229), 1 / (255. * 0.224), 1 / (255. * 0.225));
paramMobilenet.size = Size(224, 224);
paramMobilenet.swapRB = swapRB;
if (crop)
paramMobilenet.paddingmode = DNN_PMODE_CROP_CENTER;
else
paramMobilenet.paddingmode = DNN_PMODE_NULL;
//! [Create a 4D blob from a frame]
blobFromImageWithParams(frame, blob, paramMobilenet);

//! [Set input blob]
net.setInput(blob);
Mat prob = net.forward();

//! [Get a class with a highest score]
Point classIdPoint;
double confidence;
minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
int classId = classIdPoint.x;
std::string label = format("%s: %.4f", (labels.empty() ? format("Class #%d", classId).c_str() :
labels[classId].c_str()),
confidence);
putText(frame, label, Point(0, 55), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
imshow(kWinName, frame);
}
return 0;
}
Loading