herrDeng網內搜尋

自訂搜尋

Ads

2021年12月15日 星期三

C++ realsense opencv::dnn同時辨識多個小比例模型

//程式簡化,不用太新的C++ 語法 本版本修改Size參數(原300x300),可辨識更小比例模型
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <librealsense2/rs.hpp>
#include "cv-helpers.hpp"
#include <iostream>
#include <string>
using namespace cv::dnn;
using namespace cv;
using namespace rs2;
using namespace std;

int main(int argc, char** argv)
try
{ 
 cout << "本版本修改Size參數,簡化非必要參數,可辨識同時多個小比例模型\n"; 
 string classNames[] = {
 "background", "aeroplane", "bicycle", "bird", "boat","bottle", "bus", "car", "cat", "chair","cow",
 "diningtable", "dog", "horse","motorbike", "person", "pottedplant","sheep", "sofa", "train", "tvmonitor"
 };
 Net net = readNetFromCaffe("MobileNetSSD_deploy.prototxt",
 "MobileNetSSD_deploy.caffemodel");

 // Start streaming from Intel RealSense Camera
 pipeline pipe;
 config cfg;
 const int w = 1280, h = 720, FPS = 30;
 cfg.enable_stream(RS2_STREAM_COLOR, w, h, RS2_FORMAT_BGR8, FPS);
 cfg.enable_stream(RS2_STREAM_DEPTH, w, h, RS2_FORMAT_Z16, FPS);
 pipe.start(cfg);
 rs2::align align_to(RS2_STREAM_COLOR);

 string wname = "1280*720顯示辨識";
 namedWindow(wname);
 while (getWindowProperty(wname, WND_PROP_AUTOSIZE) >= 0)
 {
 frameset data = pipe.wait_for_frames();
 data = align_to.process(data);

 frame color_frame = data.get_color_frame();
 frame depth_frame = data.get_depth_frame();

 // Convert RealSense frame to OpenCV matrix:
 Mat color_mat(h, w, CV_8UC3, (void*)color_frame.get_data());;
 Mat depth_mat = depth_frame_to_meters(depth_frame);
 
 //Convert Mat to batch of images Size參數原Size(300,300)
 Mat inputBlob = blobFromImage(color_mat, 1/127.5, Size( w, h), 127.5);

 net.setInput(inputBlob, "data"); //set the network input
 Mat detection = net.forward(); //compute output

 Mat detectionMat(detection.size[2], detection.size[3], CV_32F, (float*)detection.data);
 float confidenceThreshold = 0.8;
 Vec3b color[] = {Vec3b(255,255,0), Vec3b(0, 255, 0), Vec3b(0,255, 255), Vec3b(255, 255, 127)};
 for (int i = 0; i < detectionMat.rows; i++)
 {
 putText(color_mat, "Max size of Detections: "+ to_string(detection.size[2]),
 Size(30, 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255));
 float confidence = detectionMat.at<float>(i, 2);

 if (confidence > confidenceThreshold)
 {
 size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));
 cout <<"i="<<i<<", #"<<objectClass << "\t";
 int xLeftBottom = (int)(detectionMat.at<float>(i, 3) * color_mat.cols);
 int yLeftBottom = (int)(detectionMat.at<float>(i, 4) * color_mat.rows);
 int xRightTop = (int)(detectionMat.at<float>(i, 5) * color_mat.cols);
 int yRightTop = (int)(detectionMat.at<float>(i, 6) * color_mat.rows);

 Rect object((int)xLeftBottom, (int)yLeftBottom,
 (int)(xRightTop - xLeftBottom), (int)(yRightTop - yLeftBottom)); 
 object = object & Rect(0, 0, depth_mat.cols, depth_mat.rows);
 cout << object;
 // Calculate mean depth inside the detection region
 // This is a very naive way to estimate objects depth
 Scalar m = mean(depth_mat(object));

 string ss = classNames[objectClass];
 ss += " Prob=" + to_string(confidence);
 ss += " Distance= " + to_string(100 * m[0]) + " cm ";
 cout << ss << endl;

 rectangle(color_mat, object, color[i%4], 2);
 int baseLine = 0;
 Size labelSize = getTextSize(ss, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);

 auto center = (object.br() + object.tl()) * 0.5;
 center.x = center.x - labelSize.width / 2;

 rectangle(color_mat, Rect(Point(center.x, center.y - labelSize.height),
 Size(labelSize.width, labelSize.height + baseLine)), color[i%4], -1);
 putText(color_mat, ss, center, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));
 }
 } 
 imshow(wname, color_mat);
 int k=waitKey(1);
 if (k == 27) break;
 else if (k == (int)'+') imwrite("photo.png", color_mat);
 }
 destroyAllWindows();
 pipe.stop();
 return 0;
}
catch (exception& e){
 cerr << e.what();
 return 1;
}

沒有留言:

Related Posts Plugin for WordPress, Blogger...

熱門文章