1. 程式人生 > >人臉跟蹤:簡單跟蹤

人臉跟蹤:簡單跟蹤

一、概述

       目標跟蹤是計算機視覺領域的一個重要分支。研究的人很多,近幾年也出現了很多很多的演算法。大家看看淋漓滿目的paper就知道了。但在這裡,我們也聚焦下比較簡單的演算法,看看它的優勢在哪裡。畢竟有時候簡單就是一種美。

       在這裡我們一起來欣賞下“模板匹配”這個簡單點的跟蹤演算法。它的思想很簡單,我們把要跟蹤的目標儲存好,然後在每一幀來臨的時候,我們在整個影象中尋找與這個目標最相似的,我們就相信這個就是目標了。那如何判斷相似呢?就用到了一些相關性的東西了,這個在我之前的一篇博文裡面介紹過,大家可以參考下:

       模板匹配中差值的平方和(SSD)與互相關準則的關係

       然後為了適應目標的變化,我們就需要隨時更新我們要跟蹤的目標。換句話來說,在跟蹤t幀的時候,也就是在第t幀尋找目標的時候,是與t-1幀中我們找到的目標來進行比較的。這樣目標的外觀變化就會及時的更新。這個就叫做線上跟蹤方法。當然了,這個策略會導致跟蹤漂移的問題,這就是近幾年很多跟蹤演算法關注的重要問題之一了。

二、程式碼實現

       我的程式碼是基於VS2010+ OpenCV2.4.2的。程式碼可以讀入視訊,也可以讀攝像頭,兩者的選擇只需要在程式碼中稍微修改即可。對於視訊來說,執行會先顯示第一幀,然後我們用滑鼠框選要跟蹤的目標,然後跟蹤器開始跟蹤每一幀。對攝像頭來說,就會一直採集影象,然後我們用滑鼠框選要跟蹤的目標,接著跟蹤器開始跟蹤後面的每一幀。具體程式碼如下:

simpleTracker.cpp

  1. // Object tracking algorithm using matchTemplate  
  2. // Author : zouxy  
  3. // Date   : 2013-10-28  
  4. // HomePage : http://blog.csdn.net/zouxy09  
  5. // Email  : [email protected]  
  6. #include <opencv2/opencv.hpp>  
  7. using namespace cv;  
  8. using namespace std;  
  9. // Global variables  
  10. Rect box;  
  11. bool drawing_box = false;  
  12. bool gotBB = false;  
  13. // bounding box mouse callback  
  14. void mouseHandler(int event, int x, int y, int flags, void *param){  
  15.   switch( event ){  
  16.   case CV_EVENT_MOUSEMOVE:  
  17.     if (drawing_box){  
  18.         box.width = x-box.x;  
  19.         box.height = y-box.y;  
  20.     }  
  21.     break;  
  22.   case CV_EVENT_LBUTTONDOWN:  
  23.     drawing_box = true;  
  24.     box = Rect( x, y, 0, 0 );  
  25.     break;  
  26.   case CV_EVENT_LBUTTONUP:  
  27.     drawing_box = false;  
  28.     if( box.width < 0 ){  
  29.         box.x += box.width;  
  30.         box.width *= -1;  
  31.     }  
  32.     if( box.height < 0 ){  
  33.         box.y += box.height;  
  34.         box.height *= -1;  
  35.     }  
  36.     gotBB = true;  
  37.     break;  
  38.   }  
  39. }  
  40. // tracker: get search patches around the last tracking box,  
  41. // and find the most similar one  
  42. void tracking(Mat frame, Mat &model, Rect &trackBox)  
  43. {  
  44.     Mat gray;  
  45.     cvtColor(frame, gray, CV_RGB2GRAY);  
  46.     Rect searchWindow;  
  47.     searchWindow.width = trackBox.width * 3;  
  48.     searchWindow.height = trackBox.height * 3;  
  49.     searchWindow.x = trackBox.x + trackBox.width * 0.5 - searchWindow.width * 0.5;  
  50.     searchWindow.y = trackBox.y + trackBox.height * 0.5 - searchWindow.height * 0.5;  
  51.     searchWindow &= Rect(0, 0, frame.cols, frame.rows);  
  52.     Mat similarity;  
  53.     matchTemplate(gray(searchWindow), model, similarity, CV_TM_CCOEFF_NORMED);   
  54.     double mag_r;  
  55.     Point point;  
  56.     minMaxLoc(similarity, 0, &mag_r, 0, &point);  
  57.     trackBox.x = point.x + searchWindow.x;  
  58.     trackBox.y = point.y + searchWindow.y;  
  59.     model = gray(trackBox);  
  60. }  
  61. int main(int argc, char * argv[])  
  62. {  
  63.     VideoCapture capture;  
  64.     capture.open("david.mpg");  
  65.     bool fromfile = true;  
  66.     //Init camera  
  67.     if (!capture.isOpened())  
  68.     {  
  69.         cout << "capture device failed to open!" << endl;  
  70.         return -1;  
  71.     }  
  72.     //Register mouse callback to draw the bounding box  
  73.     cvNamedWindow("Tracker", CV_WINDOW_AUTOSIZE);  
  74.     cvSetMouseCallback("Tracker", mouseHandler, NULL );   
  75.     Mat frame, model;  
  76.     capture >> frame;  
  77.     while(!gotBB)  
  78.     {  
  79.         if (!fromfile)  
  80.             capture >> frame;  
  81.         imshow("Tracker", frame);  
  82.         if (cvWaitKey(20) == 'q')  
  83.             return 1;  
  84.     }  
  85.     //Remove callback  
  86.     cvSetMouseCallback("Tracker", NULL, NULL );   
  87.     Mat gray;  
  88.     cvtColor(frame, gray, CV_RGB2GRAY);   
  89.     model = gray(box);  
  90.     int frameCount = 0;  
  91.     while (1)  
  92.     {  
  93.         capture >> frame;  
  94.         if (frame.empty())  
  95.             return -1;  
  96.         double t = (double)cvGetTickCount();  
  97.         frameCount++;  
  98.         // tracking  
  99.         tracking(frame, model, box);      
  100.         // show  
  101.         stringstream buf;  
  102.         buf << frameCount;  
  103.         string num = buf.str();  
  104.         putText(frame, num, Point(20, 20), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 3);  
  105.         rectangle(frame, box, Scalar(0, 0, 255), 3);  
  106.         imshow("Tracker", frame);  
  107.         t = (double)cvGetTickCount() - t;  
  108.         cout << "cost time: " << t / ((double)cvGetTickFrequency()*1000.) << endl;  
  109.         if ( cvWaitKey(1) == 27 )  
  110.             break;  
  111.     }  
  112.     return

相關推薦

人臉跟蹤簡單跟蹤

一、概述       目標跟蹤是計算機視覺領域的一個重要分支。研究的人很多,近幾年也出現了很多很多的演算法。大家看看淋漓滿目的paper就知道了。但在這裡,我們也聚焦下比較簡單的演算法,看看它的優勢在哪裡。畢竟有時候簡單就是一種美。       在這裡我們一起來欣賞下“模板匹

人臉跟蹤Kalman跟蹤原理講解

一、卡爾曼濾波的方程推導        直接從數學公式和概念入手來考慮卡爾曼濾波無疑是一件非常枯燥的事情。為了便於理解,我們仍然從一個現實中的例項開始下面的介紹,這一過程中你所需的預備知識僅僅是高中程度的物理學內容。        假如現在有一輛在路上做直線運動的小車(如

人臉跟蹤Goturn中的forward的前處理

void Regressor::SetMean() { // Set the mean image. mean_ = cv::Mat(input_geometry_, CV_32FC3, cv::Scalar(104, 117, 123)); } void Reg

人臉跟蹤KCF核相關濾波演算法

一直以來沒有很想寫這個,以為這個東西比較簡單,還算是比較容易理解的一個演算法,但是在知乎上回答過一個問題之後就有朋友私信我一些關於細節的東西,我一直以為關於細節的東西大家可以自己去理解,大家都是想快速瞭解這個,那我就厚臉皮了在這寫一下自己的見解了,如果有寫的不詳細或者大家想了

人臉識別即使不上傳任何照片依然能跟蹤你的個人資訊

本文為數盟原創譯文 請註明出處為數盟社群 除非你是來自俄羅斯,否則你可能從來沒有聽說過這種服務,即通過分析一個人的照片就能找到他在VK.com社交網路中的帳戶。這就是所謂的FindFace。它在2016年2月上線,最近已經頗為流行;這歸功於由聖彼得堡攝影師葉Egor

人臉跟蹤POI多目標跟蹤

網上已有很多關於MOT的文章,此係列僅為個人閱讀隨筆,便於初學者的共同成長。若希望詳細瞭解,建議閱讀原文。 本文是tracking by detection 方法進行多目標跟蹤的文章,最大的特點是使用了state-of-the-art的detection和feature

死鎖跟蹤6種跟蹤死鎖的方法總結

時間 mda msd count avi filesize microsoft win int 原文地址:http://blog.csdn.net/kk185800961/article/details/42504857 方法一:Windows 性能計數器監控 命令行輸

Spark 原始碼簡單跟蹤

本文介紹下Spark 到底是如何執行sc.TextFile(...).map(....).count() 這種程式碼的,從driver端到executor端。 另外還有pid,iter都是哪來的呢? 如果你照著原始碼點進去你會很困惑。為莫名其妙怎麼就有了這些iterator呢? Transf

乾貨閱讀跟蹤 Java 原始碼的幾個小技巧!

今天跟大家分享一下我平時閱讀原始碼的幾個小技巧,對於閱讀Java中介軟體如Spring、Dubbo等框架原始碼的同學有一定幫助。 本文基於Eclipse IDE,我們每天都使用的IDE其實提供了很多強大的功能,掌握它們,往往能夠事半功倍。 1、Quick Type Hierarchy 快速檢視類繼承體

會話跟蹤實現購物車功能

                                       小白成長記,不

目標跟蹤MDNet深度網路

論文全名:Learning Multi-Domain Convolutional Neural Networks for Visual Tracking(MDNet) 論文摘自CVPR 2016,由Hyeonseob Nam、Bohyung Han撰寫。 摘要 訓練:(1)使用大量視訊訓

目標跟蹤MTCNN報錯Check failed: registry.count(type) == 0 (1 vs. 0)

錯誤描述 當我在終端下用caffe命令對帶有PythonLayer的網路訓練時,出現瞭如下錯誤。  該錯誤提示Layer的卷積型別已經註冊過了。為什麼會出現這個錯誤呢?  其實是,博主機子上有多個Caffe版本,該版本的pycaffe介面沒有被指定正確。 解決方法

PBRT學習筆記光線跟蹤中的景深演算法

景深是人眼視覺系統中的一種自然現象。同樣,相機裡面也有景深的效果,這是由於相機的成像光圈的半徑是有一定大小的,從而導致了成相平面中的某些點可以‘看到’鏡頭外面的一部分場景,而這些場景的共同作用,導致了一種模糊現象。 景深的效果在計算機圖形學中被應用廣泛,電影,遊戲裡面經常會利

Kinect v2.0原理介紹之三骨骼跟蹤的原理

~~有興趣的小夥伴,加kinect演算法交流群:462964980。 生成3D深度的影象的原理 採用的是PrimeSence公司Light Coding技術。Light Coding技術理論是利用連續光(近紅外線)對測量空間進行編碼,經感應器讀取編碼的

目標跟蹤KCF執行流程圖(matlab版本)

前言 今天忽然看到自己寫的非常粗糙的部落格 目標跟蹤:KCF程式碼分析(matlab版本) 得到了兩個贊,感覺很開心,所以就把自己最近總結的KCF執行流程圖分享出來。 ps:換位體驗了一次部落格被

第11章 分布式服務跟蹤 Spring Cloud Sleuth

dep host framework 通過 path work 內部 分布式 ati   通常一個由客戶端發起的請求在後端系統中會經過多個不同的微服務調用來協同產生最後的請求結果, 在復雜的微服務架構系統中, 幾乎每一個前端請求都會形成一條復雜的分布式服務調用鏈路, 在每條

目標跟蹤CamShift演算法

1.前言 camshift利用目標的顏色直方圖模型將影象轉換為顏色概率分佈圖,初始化一個搜尋窗的大小和位置,並根據上一幀得到的結果自適應調整搜尋視窗的位置和大小,從而定位出當前影象中目標的中心位置

目標跟蹤系列一壓縮跟蹤(compressive tracking)

入坑滿兩年,決定開始寫關於目標跟蹤的部落格了,歡迎批評指正。 主要關注的是single-object, short-term, model-free visual tracking problem. 即單目標,短時,無模型目標跟蹤問題。 一開始是因為要做本科畢設,那時候毫

視訊目標跟蹤ECO程式碼除錯

本文只調試了ECO的MATLAB版本當中的CPU和GPU版!重點是講解如何除錯GPU版!重點是講解如何除錯GPU版!重點是講解如何除錯GPU版!我的配置環境是:matlab2018a+cuda9.0+cudnn9.0+VS2015 按照這個部落格步驟走一遍之後CPU版本

百度Apollo計劃跟蹤深度解析Apollo無人車感知和定位技術

有關無人車的定位有兩種,一種稱之為絕對定位,不依賴任何參照物,直接給出無人車相對地球座標或者說WGS84座標系,也就是座標(B,L,H),其中B為緯度,L為經度,H為大地高即是到WGS-84橢球面的高度, WGS-84座標系是美國國防部研製確定的大地座標系,是一種協議地球座標