- std::string detectNet::Mat2Base64(const cv::Mat &image, std::string imgType){
- std::vector
buf; - cv::imencode(imgType, image, buf);
- //uchar *enc_msg = reinterpret_cast
(buf.data()); - std::string img_data = base64_encode(buf.data(), buf.size(), false);
- return img_data;
- }
- void detectNet::send_json_people(cv::Mat img, std::string label, std::string level, std::string rtsp){
- std::string out = Mat2Base64(img,".jpg");
- //std::cout << out << std::endl;
-
- ImgInfo imgInfo(out, label, level, rtsp);
- static auto client = httplib::Client("127.0.0.1", 18080);
- auto result = client.Post("/uploadAlgorithmResult", imgInfo.to_json_people(), "application/json");
- if (result != nullptr && result->status == 200) {
- std::cout << result->body << std::endl;
- }
- }
其中 ImgInfo 类为:
- #ifndef HTTP_DEMO_IMGINFO_H
- #define HTTP_DEMO_IMGINFO_H
-
- #include
-
- #include "cJSON.h"
- #include "base64.h"
-
-
- #define RTSP_URL "rtsp://admin:a123456789@192.168.8.31:554/h264/ch1/main/av_stream/1"
- #define AlgorithmType "hook_detection"
- #define AlgorithmType_people "danger_zone"
- #define AlgorithmType_crooked "crooked"
-
- class ImgInfo {
- private:
- std::string img;
- std::string label;
- std::string rtsp;
- std::string level;
- public:
- ImgInfo(std::string img, std::string label,
- std::string level, std::string rtsp) : img(std::move(img)), label(std::move(label)),
- level(std::move(level)), rtsp(std::move(rtsp)) {}
-
- std::string to_json_people() {
- auto *root = cJSON_CreateObject();
- cJSON_AddStringToObject(root, "image", img.c_str());
- cJSON_AddStringToObject(root, "level", level.c_str());
- cJSON_AddStringToObject(root, "rtsp", rtsp.c_str());
- cJSON_AddStringToObject(root, "type", AlgorithmType_people);
- cJSON_AddStringToObject(root, "label", label.c_str());
-
-
- /*
- cJSON *label_array = cJSON_CreateArray();
- for (auto &i: label) {
- cJSON_AddItemToArray(label_array, cJSON_CreateString(i.c_str()));
- }
- cJSON_AddItemToObject(root, "label", label_array);
- */
- char *out = cJSON_Print(root);
- std::string res = out;
- free(out);
- cJSON_Delete(root);
- return res;
- }
- };
-
- #endif //HTTP_DEMO_IMGINFO_H
上述代码中json数据有五个部分:image为图片数据,level是告警等级,rtsp为数据流地址,type是算法类型,label是算法标签等,所以数据发送为这五个内容。
HttpServer.cpp如下:
- //#include
- //#include
- #include "HttpServer.h"
- #include
- #include
- //#include "QString"
- //#include "TimeUtils.hpp"
- //#include "AlgorithmCommon.h"
- //#include "QJsonObject"
- //#include "QJsonDocument"
- //#include "QJsonArray"
- //#include "httplib.h"
-
- //#include "log.h"
- //#include "cJSON.h"
-
- HttpServer::HttpServer(std::string ip, int port) : server_ip(ip), server_port(port) {
-
- //event_handler = new AlgorithmAlarmHandler();
-
- }
-
- HttpServer::~HttpServer() {
- stopListen();
- if (read_thd.joinable()) {
- read_thd.join();
- }
- }
-
- void HttpServer::startListen() {
- read_thd = std::thread([=]() {
- serverListen();
- });
- //event_handler->startHandlerThread();
- }
-
- void HttpServer::stopListen() {
- if (server.is_running()) {
- server.stop();
- }
- }
-
- void HttpServer::serverListen() {
- if (!server.is_valid()) {
- std::cout << "http server invalid" << std::endl;
- return;
- }
-
- // 服务器状态
- server.Get("/server/status", [&](const Request &req, Response &res) {
- onServerStatus(req, res);
- });
-
- // 上传算法结果
- server.Post("/uploadAlgorithmResult", [&](const Request &req, Response &res) {
- onUploadAlgorithmResult(req, res);
- });
-
-
- // 错误处理
- server.set_error_handler([&](const Request &req, Response &res) {
- onErrorHandle(req, res);
- });
-
- //qDebug() << "server start listen";
- server.listen(server_ip.c_str(), server_port);
- }
-
- void HttpServer::onServerStatus(const httplib::Request &req, httplib::Response &res) {
- res.body = R"({"code": 200,"msg": "Server is already Running"})";
- }
-
- void HttpServer::onUploadAlgorithmResult(const httplib::Request &req, httplib::Response &res) {
- std::string content_type = httputillib::GetContentType(req.headers);
- //if (content_type != "application/json") {
- // qDebug() << "contentType 异常, content_type:" << QString::fromStdString(content_type);
- //}
- bool parseRet = parseAlgorithmResult(req.body);
- //bool parseRet = true;
- std::string rspMsg;
- if (parseRet) {
- rspMsg = std::string(R"({"msg":"Recv Success, Parse Success."})");
- } else {
- rspMsg = std::string(R"({"msg":"Recv Success, Parse Failed."})");
- }
- res.body = std::move(rspMsg);
- }
-
-
- // 错误请求处理
- void HttpServer::onErrorHandle(const httplib::Request &req, httplib::Response &res) {
- const char *fmt = {"\"error\": \"服务器不支持该方法\""};
- char buf[BUFSIZ] = {0};
- snprintf(buf, sizeof(buf), fmt, res.status);
-
- res.set_content(buf, "application/json");
- }
-
-
- bool HttpServer::parseAlgorithmResult(const std::string &body) {
-
- //std::cout << "body:" << body << std::endl;
- Json::Reader reader;
- Json::Value root;
- //std::ifstream in(body, std::ios::binary);
- //if (!in.is_open()) {
- // std::cout << "open file failed" << std::endl;
- // return false;
- //}
- if (!reader.parse(body, root)) {
- std::cout << "parse failed" << std::endl;
- return false;
- }
- std::string rtsp = root["rtsp"].asString();
- std::cout << "rtsp:" << rtsp << std::endl;
- std::string level = root["level"].asString();
- std::cout << "level:" << level << std::endl;
- std::string type = root["type"].asString();
- std::cout << "type:" << type << std::endl;
- std::string image = root["image"].asString();
- //std::cout << "image:" << image << std::endl;
- std::string out = base64_decode(image);
- std::string decoded_jpeg = std::move(out);
- //std::cout << "decoded_jpeg: " << decoded_jpeg << std::endl;
-
- cv::Mat mat2(1, decoded_jpeg.size(), CV_8U, (char*)decoded_jpeg.data());
- cv::Mat dst = cv::imdecode(mat2, CV_LOAD_IMAGE_COLOR);
- cv::imwrite(rtsp.substr(1) + ".jpg", dst);
-
- return true;
- }
HttpServer.h如下:
- //#ifndef CPPHTTPSERVER_HTTPSERVER_H
- //#define CPPHTTPSERVER_HTTPSERVER_H
-
- #include "httputillib.h"
- #include "httplib.h"
- #include "base64.h"
- //#include "thread"
- #include
- #include
-
- #include
-
-
- class HttpServer{
- public:
- HttpServer(std::string ip, int port);
- ~HttpServer();
-
- void startListen();
-
- void stopListen();
-
- private:
-
- void serverListen();
-
- // 回调函数: 错误请求处理
- void onErrorHandle(const httplib::Request &req, httplib::Response &res);
-
- // 回调函数: 获取服务器状态
- void onServerStatus(const httplib::Request &req, httplib::Response &res);
-
- // 回调函数: 上传算法结果
- void onUploadAlgorithmResult(const httplib::Request &req, httplib::Response &res);
-
- // 回调函数:处理算法数据
- bool parseAlgorithmResult(const std::string &body);
-
- std::string server_ip;
- int server_port;
-
- Server server;
- std::thread read_thd;
-
- };
-
- //#endif //CPPHTTPLIB_HTTPLIB_H
httputillib.h如下:
- #include
-
- using namespace httplib;
-
-
- namespace httputillib {
- // 打印请求头
- static std::string DumpHeaders(const Headers &headers) {
- std::string s;
- char buf[BUFSIZ] = {0};
-
- for (auto it = headers.begin(); it != headers.end(); ++it) {
- const auto &x = *it;
- snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
- s += buf;
- }
-
- return s;
- }
-
- // 从请求同获取content type
- static std::string GetContentType(const httplib::Headers &headers) {
- auto iter = headers.find("Content-Type");
- if (iter == headers.end()) {
- return std::string();
- }
-
- return iter->second;
- }
-
- };
上述完整代码可详见github或者百度网盘