Created
November 13, 2017 23:02
-
-
Save yiling-chen/7d36389192d54f89a5fe0b810ac7bdf3 to your computer and use it in GitHub Desktop.
Usage of OpenCV C++ API to perform objection detection using MobileNet and SSD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <opencv2/dnn.hpp> | |
#include <opencv2/imgproc.hpp> | |
#include <opencv2/highgui.hpp> | |
#include <opencv2/core/utils/trace.hpp> | |
using namespace cv; | |
using namespace cv::dnn; | |
#include <fstream> | |
#include <iostream> | |
#include <cstdlib> | |
using namespace std; | |
string CLASSES[] = {"background", "aeroplane", "bicycle", "bird", "boat", | |
"bottle", "bus", "car", "cat", "chair", "cow", "diningtable", | |
"dog", "horse", "motorbike", "person", "pottedplant", "sheep", | |
"sofa", "train", "tvmonitor"}; | |
int main(int argc, char **argv) | |
{ | |
CV_TRACE_FUNCTION(); | |
String modelTxt = "MobileNetSSD_deploy.prototxt"; | |
String modelBin = "MobileNetSSD_deploy.caffemodel"; | |
String imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg"; | |
Net net = dnn::readNetFromCaffe(modelTxt, modelBin); | |
if (net.empty()) | |
{ | |
std::cerr << "Can't load network by using the following files: " << std::endl; | |
std::cerr << "prototxt: " << modelTxt << std::endl; | |
std::cerr << "caffemodel: " << modelBin << std::endl; | |
exit(-1); | |
} | |
Mat img = imread(imageFile); | |
if (img.empty()) | |
{ | |
std::cerr << "Can't read image from the file: " << imageFile << std::endl; | |
exit(-1); | |
} | |
Mat img2; | |
resize(img, img2, Size(300,300)); | |
Mat inputBlob = blobFromImage(img2, 0.007843, Size(300,300), Scalar(127.5, 127.5, 127.5), false); | |
net.setInput(inputBlob, "data"); | |
Mat detection = net.forward("detection_out"); | |
Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>()); | |
ostringstream ss; | |
float confidenceThreshold = 0.2; | |
for (int i = 0; i < detectionMat.rows; i++) | |
{ | |
float confidence = detectionMat.at<float>(i, 2); | |
if (confidence > confidenceThreshold) | |
{ | |
int idx = static_cast<int>(detectionMat.at<float>(i, 1)); | |
int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * img.cols); | |
int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * img.rows); | |
int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * img.cols); | |
int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * img.rows); | |
Rect object((int)xLeftBottom, (int)yLeftBottom, | |
(int)(xRightTop - xLeftBottom), | |
(int)(yRightTop - yLeftBottom)); | |
rectangle(img, object, Scalar(0, 255, 0), 2); | |
cout << CLASSES[idx] << ": " << confidence << endl; | |
ss.str(""); | |
ss << confidence; | |
String conf(ss.str()); | |
String label = CLASSES[idx] + ": " + conf; | |
int baseLine = 0; | |
Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); | |
putText(img, label, Point(xLeftBottom, yLeftBottom), | |
FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,0,0)); | |
} | |
} | |
imshow("detections", img); | |
waitKey(); | |
return 0; | |
} |
What is the purpose of L41? resize(img, img2, Size(300,300));
... from what I understand the MobileNetSSD model already does this, doing it here just adds additional overhead. Testing shows it is not needed and causes quite a performance hit when using CPU.
My code works, but I don't have any reasonable outputs. I modified the code slightly to output detections before the image postprocessing happens. This is what I get:
Found 1 detection(s):
ID: -431602080 Confidence: -431602080
What could cause the problem?
I don't know: "Does exactly this code works?", but I took a few lines code from here and everything works nice. Thanks for help=)
All Right. It works thanks!
It works! great! thanks a lot
good! It can work!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I got an error like this:
"terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.1.2-pre) opencv/modules/dnn/src/caffe/caffe_io.cpp:1121: error: (-2:Unspecified error) FAILED: fs.is_open(). Can't open "MobileNetSSD_deploy.prototxt" in function 'ReadProtoFromTextFile'"
I just changed line 21: I added '.txt' at "MobileNetSSD_deploy.prototxt". (like this) "MobileNetSSD_deploy.prototxt.txt"