c++ 解析從瀏覽器端傳過來的影象base64編碼,並轉換成opencv識別的格式
#include <cstdint> #include <fstream> #include <iostream> #include <string> #include <vector> #include "opencv2/core/core.hpp" #include "opencv2/contrib/contrib.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/objdetect/objdetect.hpp" #include <b64/encode.h> #include <b64/decode.h> #include "face_detection.h" using namespace cv; using namespace std; cv::Mat img_gray; static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } Mat deserialize(std::stringstream& input) { // The data we need to deserialize int width = 0; int height = 0; int type = 0; size_t size = 0; // Read the width, height, type and size of the buffer input.read((char*)(&width), sizeof(int)); input.read((char*)(&height), sizeof(int)); input.read((char*)(&type), sizeof(int)); input.read((char*)(&size), sizeof(size_t)); // Allocate a buffer for the pixels char* data = new char[size]; // Read the pixels from the stringstream input.read(data, size); // Construct the image (clone it so that it won't need our buffer anymore) Mat m = Mat(height, width, type, data).clone(); // Delete our buffer delete[]data; // Return the matrix return m; } Mat getFaceRec(Mat img, seeta::FaceDetection *detector) { if (img.channels() != 1) cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); else img_gray = img; seeta::ImageData img_data; img_data.data = img_gray.data; img_data.width = img_gray.cols; img_data.height = img_gray.rows; img_data.num_channels = 1; std::vector<seeta::FaceInfo> faces = detector->Detect(img_data); cv::Rect face_rect; int32_t num_face = static_cast<int32_t>(faces.size()); for (int32_t i = 0; i < num_face; i++) { face_rect.x = faces[i].bbox.x; face_rect.y = faces[i].bbox.y; face_rect.width = faces[i].bbox.width; face_rect.height = faces[i].bbox.height; cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0); } return img; } std::string base64_decode(std::string const& encoded_string) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i == 4) { for (i = 0; i < 4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } } if (i) { for (j = i; j < 4; j++) char_array_4[j] = 0; for (j = 0; j < 4; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; } return ret; } void getBBoxOfFace(string path,char* modelPath) { seeta::FaceDetection *detector = new seeta::FaceDetection(modelPath); detector->SetMinFaceSize(40); detector->SetScoreThresh(2.f); detector->SetImagePyramidScaleFactor(0.8f); detector->SetWindowStep(4, 4); Mat img = cv::imread(path); if (img.channels() != 1) cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); else img_gray = img; seeta::ImageData img_data; img_data.data = img_gray.data; img_data.width = img_gray.cols; img_data.height = img_gray.rows; img_data.num_channels = 1; std::vector<seeta::FaceInfo> faces = detector->Detect(img_data); cv::Rect face_rect; int32_t num_face = static_cast<int32_t>(faces.size()); for (int32_t i = 0; i < num_face; i++) { face_rect.x = faces[i].bbox.x; face_rect.y = faces[i].bbox.y; face_rect.width = faces[i].bbox.width; face_rect.height = faces[i].bbox.height; cout<<face_rect.x<<","<<face_rect.y<<","<<face_rect.width<<","<<face_rect.height<<endl; //cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0); } } void seetaFaceDetectorByBase64Path(string path,char* modelPath) { seeta::FaceDetection *detector = new seeta::FaceDetection(modelPath); detector->SetMinFaceSize(40); detector->SetScoreThresh(2.f); detector->SetImagePyramidScaleFactor(0.8f); detector->SetWindowStep(4, 4); base64::decoder D; std::ifstream fin(path); std::string strRs; std::string str; while (fin) { fin >> str; strRs += str; } /* std::stringstream decoded; std::stringstream ss(strRs); D.decode(ss, decoded); //base64解密 Mat img = deserialize(decoded); //反序列化 */ std::string decoded_string = base64_decode(strRs); std::vector<uchar> data(decoded_string.begin(), decoded_string.end()); Mat img = imdecode(data, IMREAD_UNCHANGED); //cv::imshow("img",img); //cv::waitKey(0); //檢測人臉 if (img.channels() != 1) cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); else img_gray = img; seeta::ImageData img_data; img_data.data = img_gray.data; img_data.width = img_gray.cols; img_data.height = img_gray.rows; img_data.num_channels = 1; std::vector<seeta::FaceInfo> faces = detector->Detect(img_data); cv::Rect face_rect; int32_t num_face = static_cast<int32_t>(faces.size()); for (int32_t i = 0; i < num_face; i++) { face_rect.x = faces[i].bbox.x; face_rect.y = faces[i].bbox.y; face_rect.width = faces[i].bbox.width; face_rect.height = faces[i].bbox.height; cout<<face_rect.x<<","<<face_rect.y<<","<<face_rect.width<<","<<face_rect.height<<endl; //cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0); } } void seetaFaceDetectorByBase64Str(string encoded_string,char* modelPath) { seeta::FaceDetection *detector = new seeta::FaceDetection(modelPath); detector->SetMinFaceSize(40); detector->SetScoreThresh(2.f); detector->SetImagePyramidScaleFactor(0.8f); detector->SetWindowStep(4, 4); base64::decoder D; std::string decoded_string = base64_decode(encoded_string); std::vector<uchar> data(decoded_string.begin(), decoded_string.end()); Mat img = imdecode(data, IMREAD_UNCHANGED); //cv::imshow("img",img); //cv::waitKey(0); //檢測人臉 if (img.channels() != 1) cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); else img_gray = img; seeta::ImageData img_data; img_data.data = img_gray.data; img_data.width = img_gray.cols; img_data.height = img_gray.rows; img_data.num_channels = 1; std::vector<seeta::FaceInfo> faces = detector->Detect(img_data); cv::Rect face_rect; int32_t num_face = static_cast<int32_t>(faces.size()); for (int32_t i = 0; i < num_face; i++) { face_rect.x = faces[i].bbox.x; face_rect.y = faces[i].bbox.y; face_rect.width = faces[i].bbox.width; face_rect.height = faces[i].bbox.height; cout<<face_rect.x<<","<<face_rect.y<<","<<face_rect.width<<","<<face_rect.height<<endl; //cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0); } } int main(int argc, char** argv) { //視訊路徑 模型路徑 if(argc != 3) { std::cout<<"argument fault"<<std::endl; return 0; } //getBBoxOfFace(argv[1],argv[2]); seetaFaceDetectorByBase64Str(argv[1],argv[2]); /* Mat frame; char path[100]; int count = 0; seeta::FaceDetection *detector = new seeta::FaceDetection(argv[2]); detector->SetMinFaceSize(40); detector->SetScoreThresh(2.f); detector->SetImagePyramidScaleFactor(0.8f); detector->SetWindowStep(4, 4); getBBoxOfFace(string path,string modelPath); VideoCapture capture(argv[1]); while(true) { capture >> frame; //獲得了最後一幀 if(frame.empty()) { break; } frame = getFaceRec(frame,detector); sprintf(path,"/home/lgf/ext_data/videoFace/%d.jpg",count++); cv2.imwrite(path,) cv::namedWindow("SeetaFaceDetect", cv::WINDOW_AUTOSIZE); cv::imshow("Test", frame); cv::waitKey(1); } cv::destroyAllWindows(); */ }
相關推薦
c++ 解析從瀏覽器端傳過來的影象base64編碼,並轉換成opencv識別的格式
#include <cstdint> #include <fstream> #include <iostream> #include <string> #include <vector> #includ
前端傳遞url引數中有中文,後端傳過來的有亂碼,解決方案
一、問題重現: 原始碼:用get方式傳遞 @ResponseBody @RequestMapping(value = {"/findGroupByGroupName/{batchNo
C#中從記憶體空間的角度看資料型別,並延申到static方法的分析
資料型別這篇文章主要討論的是值型別和引用型別,值型別在定義的時候就會將該值儲存在棧中,而引用型別是分配在堆中,在堆中存放的是資料區域地址,它用來指向一塊記憶體空間。棧可以理解為儲存的都是一些資料變數,而堆中放的都是一些例項化物件。在對值型別操作時不會影響其他值,而當引用變數引用其他引用變數時
Django 模板語言從後端傳到前端
後端 htm html [1] dex cal views 列表 渲染 如果我們在後端有數據動態提取到前端的時候 就需要模板語言加以渲染後再將渲染好的HTML文件傳入前端 我們的views.py裏的index函數裏有個s變量是個列表,將數據以大括號的形式傳入{"l
前端接受後端傳過來的list的處理
== uid lse debugger 用戶權限 .data ber ole ati //隱藏需要權限才顯示的分配按鈕 $("#btn-distribute").css("display", "none");
前臺傳過來的json資料,解析request
/** * 解析前臺獲得的互動資料 * @param request * @return * @throws IOException */ public static JSONObject getJsonObject(HttpServletRequest re
MVC使用ajax非同步重新整理時怎樣輸出從後臺中傳過來的JSON資料
前言 這幾天在學習MVC使用AJAX非同步刷,因為是新手。所以在js中傳引數到後臺以及後臺返回資料到前臺怎麼接受,怎麼前臺遍歷出JSON資料都開始不知道,相信新手在使用時跟我一樣會遇到,這裡我就和大家分享一下。新手勿噴。。。 這裡使用VS2010中新建的mvc 3.0專案
客戶端/伺服器模式C/S與瀏覽器端/伺服器模式B/S
客戶端/伺服器模式與瀏覽器端/伺服器模式,即C/S模式與B/S模式之間的區別,其實與RCP和TCP程式的區別一樣,在於執行平臺和資料交換模式的區別。 C/S模式中,在客戶端需要安裝RCP程式,負責客戶
netty處理客戶端傳過來的get、post、websocket資料例子
package com.penngo.http; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import
Binder原始碼解析(從客戶端到服務端程式碼流程)
Binder 解析(從客戶端到服務端程式碼流程) 首先從一個例子開始 服務端程式碼: public class WeatherService extends Service{ IWeatherInterface.Stub stub = new
使用HttpClient傳送http請求,並解析從伺服器端返回的資料
使用Apache的httpclient包可以模擬HTTP請求的傳送, get和post均可以。最方便的地方就是請求struts等web框架進行測試,省去了做測試頁面的差事。import java.io.IOException; import java.io.InputStr
php獲取ios或android通過文件頭(header)傳過來的坐標,通過百度接口獲取具體城市和地址,並存入到session中。
word 請求 sse 百度 頭文件 reac session ray 位置 首先,在function.php方法文件中封裝一個獲取header頭文件的方法。 if (!function_exists(‘getallheaders‘)) { function g
使用openlayer中的filter從後端返回滿足查詢條件的要素並顯示屬性資訊
本功能主要參考官網的filter例子,地址如下 該功能主要實現了在右上方選擇需要查詢要輸的欄位,並輸入相應欄位要查詢的值,支援模糊查詢,在點選查詢之後,地圖介面上顯示查詢出的要素並定位到這些要素,
Springmvc檔案上傳例子,上傳帶圖片的Excel,並利用poi解析。
直奔主題,第一步:上傳一個帶圖片的Excel。第二步:解析該Excel檔案,得到Excel資料和圖片。 1.pom.xml <!-- 檔案上傳 --> <dependency> <groupId>commons-
c#控制IE瀏覽器自動點選等事件WebBrowser,mshtml.IHTMLDocument2
可以實現例如通過應用程式操作google搜尋,使用者輸入要搜尋的內容,然後在google中搜索;可以自動點選網頁上的按鈕等功能 1. 加入對Microsoft Internet Controls的引用; 2. 加入對Microsoft HTML Object
JSP頁面中獲取從controller中傳遞過來的時間資料,顯示格式
首先jsp頁面頂部要包含<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> 然後再頁面中使用如下: <fmt:formatDate value="${product.update
玩玩Linux雲主機-使用XShell從Windows上傳檔案到Linux伺服器,下載到本地
之前搭建好了,對於這個操作啊,基本上的東西還是懂一點點,實在搞不懂就百度一下子。我記得之前使用虛擬機器的時候,想從windows複製檔案到虛擬機器中很簡單啊,直接的copy然後貼上,可是現在不行了啊,
從瀏覽器輸入URL到網頁載入完成,發生了什麼?
這個我打算分為兩部門來說。第一部分是從鍵盤輸入到螢幕顯示URL;第二部分是按下回車後,到頁面載入的過程。 第一部分在(),本文將著重討論第二部分。 一、DNS解析 DNS解析的過程是一個先在本地機器上找,然後去網路上找的過程。首先,會先去瀏覽器快取中查詢,沒有就去本機的h
c# WPF客戶端調用WebAPI並轉換成List
protect pre orm dsv 列表 void response () res 利用HttpClient、JsonConvert實現。 引用Newtonsoft.Json.dll和System.Net.Http。 舉個例子:從webapi中獲取設備列表。 pub
DOS批處理器移動指定數量文件到一個臨時文件夾,上傳到linux服務器,並刪除臨時文件夾下的文件
dosDOS批處理器移動指定數量文件到一個臨時文件夾,上傳到linux服務器,並刪除臨時文件夾下的文件,上傳需要依賴pscp.exe。腳本如下:@echo off&setlocal enabledelayedexpansion #將400個xml文件從M:\dockerEPG\目錄下移動到M:\scp