人臉跟蹤:Goturn中的forward的前處理
void Regressor::SetMean() { // Set the mean image. mean_ = cv::Mat(input_geometry_, CV_32FC3, cv::Scalar(104, 117, 123)); } void Regressor::Init() { if (modified_params_ ) { printf("Reloading new params\n"); net_->CopyTrainedLayersFrom(caffe_model_); modified_params_ = false; } } void Regressor::Regress(const cv::Mat& image_curr, const cv::Mat& image, const cv::Mat& target, BoundingBox* bbox) { assert(net_->phase() == caffe::TEST); // Estimate the bounding box location of the target object in the current image. std::vector<float> estimation; Estimate(image, target, &estimation); // Wrap the estimation in a bounding box object. *bbox = BoundingBox(estimation); } void Regressor::Estimate(const cv::Mat& image, const cv::Mat& target, std::vector<float>* output) { assert(net_->phase() == caffe::TEST); // Reshape the input blobs to be the appropriate size. Blob<float>* input_target = net_->input_blobs()[0]; input_target->Reshape(1, num_channels_, input_geometry_.height, input_geometry_.width); Blob<float>* input_image = net_->input_blobs()[1]; input_image->Reshape(1, num_channels_, input_geometry_.height, input_geometry_.width); Blob<float>* input_bbox = net_->input_blobs()[2]; input_bbox->Reshape(1, 4, 1, 1); // Forward dimension change to all layers. net_->Reshape(); // Process the inputs so we can set them. std::vector<cv::Mat> target_channels; std::vector<cv::Mat> image_channels; WrapInputLayer(&target_channels, &image_channels); // Set the inputs to the network. Preprocess(image, &image_channels); Preprocess(target, &target_channels); // Perform a forward-pass in the network. net_->ForwardPrefilled(); // Get the network output. GetOutput(output); } void Regressor::ReshapeImageInputs(const size_t num_images) { // Reshape the input blobs to match the given size and geometry. Blob<float>* input_target = net_->input_blobs()[0]; input_target->Reshape(num_images, num_channels_, input_geometry_.height, input_geometry_.width); Blob<float>* input_image = net_->input_blobs()[1]; input_image->Reshape(num_images, num_channels_, input_geometry_.height, input_geometry_.width); } void Regressor::GetFeatures(const string& feature_name, std::vector<float>* output) const { //printf("Getting %s features\n", feature_name.c_str()); // Get a pointer to the requested layer. const boost::shared_ptr<Blob<float> > layer = net_->blob_by_name(feature_name.c_str()); // Compute the number of elements in this layer. int num_elements = 1; for (int i = 0; i < layer->num_axes(); ++i) { const int elements_in_dim = layer->shape(i); //printf("Layer %d: %d\n", i, elements_in_dim); num_elements *= elements_in_dim; } //printf("Total num elements: %d\n", num_elements); // Copy all elements in this layer to a vector. const float* begin = layer->cpu_data(); const float* end = begin + num_elements; *output = std::vector<float>(begin, end); } void Regressor::SetImages(const std::vector<cv::Mat>& images, const std::vector<cv::Mat>& targets) { if (images.size() != targets.size()) { printf("Error - %zu images but %zu targets\n", images.size(), targets.size()); } const size_t num_images = images.size(); // Set network inputs to the appropriate size and number. ReshapeImageInputs(num_images); // Wrap the network inputs with opencv objects. std::vector<std::vector<cv::Mat> > target_channels; std::vector<std::vector<cv::Mat> > image_channels; WrapInputLayer(num_images, &target_channels, &image_channels); // Set the network inputs appropriately. Preprocess(images, &image_channels); Preprocess(targets, &target_channels); } void Regressor::Estimate(const std::vector<cv::Mat>& images, const std::vector<cv::Mat>& targets, std::vector<float>* output) { assert(net_->phase() == caffe::TEST); // Set the inputs to the network. SetImages(images, targets); // Forward dimension change to all layers. net_->Reshape(); // Perform a forward-pass in the network. net_->ForwardPrefilled(); // Get the network output. GetOutput(output); } void Regressor::GetOutput(std::vector<float>* output) { // Get the fc8 output features of the network (this contains the estimated bounding box). GetFeatures("fc8", output); } // Wrap the input layer of the network in separate cv::Mat objects // (one per channel). This way we save one memcpy operation and we // don't need to rely on cudaMemcpy2D. The last preprocessing // operation will write the separate channels directly to the input // layer. void Regressor::WrapInputLayer(std::vector<cv::Mat>* target_channels, std::vector<cv::Mat>* image_channels) { Blob<float>* input_layer_target = net_->input_blobs()[0]; Blob<float>* input_layer_image = net_->input_blobs()[1]; int target_width = input_layer_target->width(); int target_height = input_layer_target->height(); float* target_data = input_layer_target->mutable_cpu_data(); for (int i = 0; i < input_layer_target->channels(); ++i) { cv::Mat channel(target_height, target_width, CV_32FC1, target_data); target_channels->push_back(channel); target_data += target_width * target_height; } int image_width = input_layer_image->width(); int image_height = input_layer_image->height(); float* image_data = input_layer_image->mutable_cpu_data(); for (int i = 0; i < input_layer_image->channels(); ++i) { cv::Mat channel(image_height, image_width, CV_32FC1, image_data); image_channels->push_back(channel); image_data += image_width * image_height; } } // Wrap the input layer of the network in separate cv::Mat objects // (one per channel). This way we save one memcpy operation and we // don't need to rely on cudaMemcpy2D. The last preprocessing // operation will write the separate channels directly to the input // layer. void Regressor::WrapInputLayer(const size_t num_images, std::vector<std::vector<cv::Mat> >* target_channels, std::vector<std::vector<cv::Mat> >* image_channels) { Blob<float>* input_layer_target = net_->input_blobs()[0]; Blob<float>* input_layer_image = net_->input_blobs()[1]; image_channels->resize(num_images); target_channels->resize(num_images); int target_width = input_layer_target->width(); int target_height = input_layer_target->height(); float* target_data = input_layer_target->mutable_cpu_data(); for (int n = 0; n < num_images; ++n) { for (int i = 0; i < input_layer_target->channels(); ++i) { cv::Mat channel(target_height, target_width, CV_32FC1, target_data); (*target_channels)[n].push_back(channel); target_data += target_width * target_height; } } int image_width = input_layer_image->width(); int image_height = input_layer_image->height(); float* image_data = input_layer_image->mutable_cpu_data(); for (int n = 0; n < num_images; ++n) { for (int i = 0; i < input_layer_image->channels(); ++i) { cv::Mat channel(image_height, image_width, CV_32FC1, image_data); (*image_channels)[n].push_back(channel); image_data += image_width * image_height; } } } void Regressor::Preprocess(const cv::Mat& img, std::vector<cv::Mat>* input_channels) { // Convert the input image to the input image format of the network. cv::Mat sample; if (img.channels() == 3 && num_channels_ == 1) cv::cvtColor(img, sample, CV_BGR2GRAY); else if (img.channels() == 4 && num_channels_ == 1) cv::cvtColor(img, sample, CV_BGRA2GRAY); else if (img.channels() == 4 && num_channels_ == 3) cv::cvtColor(img, sample, CV_BGRA2BGR); else if (img.channels() == 1 && num_channels_ == 3) cv::cvtColor(img, sample, CV_GRAY2BGR); else sample = img; // Convert the input image to the expected size. cv::Mat sample_resized; if (sample.size() != input_geometry_) cv::resize(sample, sample_resized, input_geometry_); else sample_resized = sample; // Convert the input image to the expected number of channels. cv::Mat sample_float; if (num_channels_ == 3) sample_resized.convertTo(sample_float, CV_32FC3); else sample_resized.convertTo(sample_float, CV_32FC1); // Subtract the image mean to try to make the input 0-mean. cv::Mat sample_normalized; cv::subtract(sample_float, mean_, sample_normalized); // This operation will write the separate BGR planes directly to the // input layer of the network because it is wrapped by the cv::Mat // objects in input_channels. cv::split(sample_normalized, *input_channels); /*CHECK(reinterpret_cast<float*>(input_channels->at(0).data) == net_->input_blobs()[0]->cpu_data()) << "Input channels are not wrapping the input layer of the network.";*/ } void Regressor::Preprocess(const std::vector<cv::Mat>& images, std::vector<std::vector<cv::Mat> >* input_channels) { for (size_t i = 0; i < images.size(); ++i) { const cv::Mat& img = images[i]; // Convert the input image to the input image format of the network. cv::Mat sample; if (img.channels() == 3 && num_channels_ == 1) cv::cvtColor(img, sample, CV_BGR2GRAY); else if (img.channels() == 4 && num_channels_ == 1) cv::cvtColor(img, sample, CV_BGRA2GRAY); else if (img.channels() == 4 && num_channels_ == 3) cv::cvtColor(img, sample, CV_BGRA2BGR); else if (img.channels() == 1 && num_channels_ == 3) cv::cvtColor(img, sample, CV_GRAY2BGR); else sample = img; // Convert the input image to the expected size. cv::Mat sample_resized; if (sample.size() != input_geometry_) cv::resize(sample, sample_resized, input_geometry_); else sample_resized = sample; // Convert the input image to the expected number of channels. cv::Mat sample_float; if (num_channels_ == 3) sample_resized.convertTo(sample_float, CV_32FC3); else sample_resized.convertTo(sample_float, CV_32FC1); // Subtract the image mean to try to make the input 0-mean. cv::Mat sample_normalized; cv::subtract(sample_float, mean_, sample_normalized); // This operation will write the separate BGR planes directly to the // input layer of the network because it is wrapped by the cv::Mat // objects in input_channels. cv::split(sample_normalized, (*input_channels)[i]); /*CHECK(reinterpret_cast<float*>(input_channels->at(0).data) == net_->input_blobs()[0]->cpu_data()) << "Input channels are not wrapping the input layer of the network.";*/ } }
相關推薦
人臉跟蹤:Goturn中的forward的前處理
void Regressor::SetMean() { // Set the mean image. mean_ = cv::Mat(input_geometry_, CV_32FC3, cv::Scalar(104, 117, 123)); } void Reg
人臉跟蹤:Kalman跟蹤原理講解
一、卡爾曼濾波的方程推導 直接從數學公式和概念入手來考慮卡爾曼濾波無疑是一件非常枯燥的事情。為了便於理解,我們仍然從一個現實中的例項開始下面的介紹,這一過程中你所需的預備知識僅僅是高中程度的物理學內容。 假如現在有一輛在路上做直線運動的小車(如
Python基礎(15):python中的異常處理機制
異常:程式執行過程中由外部問題(硬體錯誤,輸入錯誤)引起的異常事件。 捕獲異常 語法: try: <語句> except <名字>:#異常1名字
人臉識別:NormFace中疑問和總結
今天介紹一下NormFace: L2 Hypersphere Embedding for Face Verification Motivation 希望利用正則化解決兩個問題:1. 人臉識別任務裡面的loss有softmax、contrastive、triplet、pai
ABP原始碼分析四十七:ABP中的異常處理
ABP 中異常處理的思路是很清晰的。一共五種型別的異常類。 AbpInitializationException用於封裝ABP初始化過程中出現的異常,只要丟擲AbpInitializationException異常就可以,無須做額外處理。這類異常往往是需要維護人員介入分析的。 其他四個異常都在AbpCon
人臉跟蹤:KCF核相關濾波演算法
一直以來沒有很想寫這個,以為這個東西比較簡單,還算是比較容易理解的一個演算法,但是在知乎上回答過一個問題之後就有朋友私信我一些關於細節的東西,我一直以為關於細節的東西大家可以自己去理解,大家都是想快速瞭解這個,那我就厚臉皮了在這寫一下自己的見解了,如果有寫的不詳細或者大家想了
人臉跟蹤:POI多目標跟蹤
網上已有很多關於MOT的文章,此係列僅為個人閱讀隨筆,便於初學者的共同成長。若希望詳細瞭解,建議閱讀原文。 本文是tracking by detection 方法進行多目標跟蹤的文章,最大的特點是使用了state-of-the-art的detection和feature
人臉跟蹤:簡單跟蹤
一、概述 目標跟蹤是計算機視覺領域的一個重要分支。研究的人很多,近幾年也出現了很多很多的演算法。大家看看淋漓滿目的paper就知道了。但在這裡,我們也聚焦下比較簡單的演算法,看看它的優勢在哪裡。畢竟有時候簡單就是一種美。 在這裡我們一起來欣賞下“模板匹
前端面試題:JS中的let和var的區別
blog ocs undefine define 規範 target {} 擁有 comment 最近很多前端的朋友去面試被問到let和var的區別,其實阮一峰老師的ES6中已經很詳細介紹了let的用法和var的區別。我簡單總結一下,以便各位以後面試中使用。 ES6 新增
翻譯:XtraDB/InnoDB中的AUTO_INCREMENT處理方式(已提交到MariaDB官方手冊)
16px targe ron 架構 href family 右下角 incr 點擊 本文為mariadb官方手冊:XtraDB/InnoDB中的AUTO_INCREMENT處理方式的譯文。 原文:https://mariadb.com/kb/en/auto_increm
數據結構35:二叉樹前序遍歷、中序遍歷和後序遍歷
tdi 代碼 nod 完成 循環 同時 reat pan 設置 遞歸算法底層的實現使用的是棧存儲結構,所以可以直接使用棧寫出相應的非遞歸算法。 先序遍歷的非遞歸算法 從樹的根結點出發,遍歷左孩子的同時,先將每個結點的右孩子壓棧。當遇到結點沒有左孩子的時候,取棧頂的右
webpack 對 css 壓縮中對前綴的處理
IV In kit top bsp asset load 規則 plugin 在 vue-cli 創建的項目中,用默認的 webpack 配置對項目打包後,發現 css 文件中樣式的前綴有所缺失,例如:flex 這個應該有前綴的屬性卻沒有(display:-webkit-f
由散列表到BitMap的概念與應用(三):面試中的海量資料處理
一道面試題 在面試軟體開發工程師時,經常會遇到海量資料排序和去重的面試題,特別是大資料崗位。 例1:給定a、b兩個檔案,各存放50億個url,每個url各佔64位元組,記憶體限制是4G,找出a、b檔案共同的url? 首先我們最常想到的方法是讀取檔案a,建立雜湊表,然後再讀取檔案b,遍歷檔
Shell-case:指令碼中在yum安裝軟體包前如何對環境進行檢測
最近一直忙於學習Linux的知識,寫了不少東西都是自己當天學的Linux知識,還有一些自己當天的知識總結,已經很久沒有寫過正兒八經寫寫自己研究分析出來的演算法,這個國慶節沒什麼事做,就一些具體的需求,做了點研究,結合學過的shell指令碼的知識,做了幾個指令
requests(三):json請求中中文亂碼處理
最近收到一個問題:json格式請求資料中有中文,導致服務端簽名失敗。 問題詳情: 一位同學在傳送json格式的post請求時,請求資料中有中文內容: {"inputCodes":["6932608700850"],"terminal":{"status":1,"channel":"D002
Linux中斷(interrupt)子系統之三:中斷流控處理層
1. 中斷流控層簡介 早期的核心版本中,幾乎所有的中斷都是由__do_IRQ函式進行處理,但是,因為各種中斷請求的電氣特性會有所不同,又或者中斷控制器的特性也不同,這會導致以下這些處理也會有所不同: 何時對中斷控制器發出ack迴應; mask_irq
[Xcode10 實際操作]九、實用進階-(18)影象人臉識別:對圖片中的人像進行面部檢測
本文將演示對圖片中的人像,進行面部檢測。 在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】 1 import UIKit 2 //匯入要使用的CoreImage框架 3 //該框架提供了強大和高效的圖片處理功能。 4 //用來對基於畫素的影象進行分析
影象處理三:影象變形forward warping和inverse warping
一、影象變形 假設原影象為f(u,v),扭曲的目標影象是g(x,y) 1. forward warping 在已知影象座標轉換關係x(u,v)和y(u,v),直接把原圖座標對映到轉換後圖像相對應的位置上,近似取整得到結果。
分享知識-快樂自己:Spring中的(三種)異常處理機制
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSch
已知中序、後序構造二叉樹(關鍵詞:二叉樹/前序/先序/中序/後序/先根/中根/後根/遍歷/搜尋/查詢)
已知中序、後序構造二叉樹 遞迴演算法 def buildTree(inorder, postorder): if inorder and postorder: postRootVal = postorder