from:
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(); */ }