1. 程式人生 > >c++ 解析從瀏覽器端傳過來的影象base64編碼,並轉換成opencv識別的格式

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瀏覽器自動點選等事件WebBrowsermshtml.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雲主機-使用XShellWindows上檔案到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