1. 程式人生 > >應用OpenCV檢測自定義目標

應用OpenCV檢測自定義目標

最近做了一個目標檢測的應用,通過大量的待檢測目標的樣本進行訓練,得到分類器;然後輸入測試視訊,看分類器的檢測結果。主要應用了OpenCV自帶的工具:

1.opencv\build\x86\vc10\bin下的opencv_createsamples.exe

2.opencv\build\x86\vc10\bin下的opencv_traincascade.exe

訓練的演算法是adaboost級聯分類器。關於adaboost的演算法講解,這篇博文有不錯的講解:http://blog.csdn.net/mousever/article/details/52038198

opencv_traincascade提供了三種不同的特徵提取方式:Haar,LBP,HOG。在本次應用中,待檢測的目標如下圖藍色橢圓中所示:


整體的步驟流程如下:

1、 正負樣本的建立;

2、 利用樣本,訓練分類器;

3、 利用訓練好的分類器進行目標檢測。

訓練樣本分為正樣本和反樣本。正樣本是指待檢測的目標樣本(例如汽車,人臉,標誌物等),反例樣本指不包含正樣本的背景圖片(需要注意的是,這些反例樣本儘量是出現正樣本場景中的背景圖片),所有的樣本圖片都被歸一化為同樣的尺寸大小(例如,20x20、20x30)。 在本次演示工程中,通過攝像頭在不同光照、不同旋轉角度下拍攝待檢測物體的照片,然後對圖片進行摳圖,得到正樣本。得到的樣本數量約為500~1000個。然後拍攝正樣本可能的背景畫面,得到負樣本數量約為1000~1500個。得到正樣本後,利用OpenCV函式庫中的CreateSamples.exe工具生成正樣本描述檔案。這個檔案是接下來訓練要用的,可以看做是正樣本特徵的第一步提取。關於opencv_createsamples.exe的執行命令引數,可以查詢此篇部落格:http://blog.csdn.net/wuxiaoyao12/article/details/39227189。opencv_createsamples命令為:

opencv_createsamples.exe -info info.txt -vec vector.vec -num 700 -w 20 -h 30

訓練階段演算法採用了adaboost(自適應增強)演算法,這是一種級聯分類器的演算法,將多個性能較弱的分類器級聯,組合成一種效能強的分類器。它的自適應在於:前一個基本分類器分錯的樣本會得到加強,加權後的全體樣本再次被用來訓練下一個基本分類器。同時,在每一輪中加入一個新的弱分類器,直到達到某個預定的足夠小的錯誤率或達到預先指定的最大迭代次數。OpenCV提供了開源的adaboost演算法庫,可以比較方便的呼叫;而對於應用,比較重要的一點是特徵的選取。通常,樣本可以用Haar、HOG、LBP等特徵描述,例如人臉,用Haar效果比較好,而對於行人,用HOG效果比較好。在應用時,應分析物體特徵,選擇較好的特徵提取演算法。opencv_traincascade命令為:

opencv_traincascade.exe -data data/cascade -vec data/vector.vec -bg negative/infofile.txt -numPos 600 -numNeg 1000 -numStages 20 -featureType LBP -mode ALL -w 20 -h 30 

值得注意的是其中的numPos引數,並非為createsamples階段採用的700,否則會報錯。建議為num的0.8~0.9。另外經過測試,對於featureType引數,LBP比HAAR效果相差無幾,但訓練速度快了很多。

經過訓練可以得到分類器。測試訓練效果如圖所示,藍色橢圓框內為檢測到的物體:


最後,附上原始碼。

1)產生正樣本圖片的原始碼。通過攝像頭採集影象,在影象中設定一個矩形框並繪製在影象中,作為採集樣本的區域。按s鍵儲存樣本圖片,並歸一化成20*30大小。

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <ctype.h>

using namespace cv;
using namespace std;

Mat image;
bool selectObje

        selection &= Rect(0, 0, image.cols, image.rows);

    }

    switch( event )
    {
    case CV_EVENT_LBUTTONDOWN:
        origin = Point(x,y);
        selection = Rect(x,y,0,0);
        selectObject = true;
        break;
    case CV_EVENT_LBUTTONUP:
        selectObject = false;
		write_en = true;
        break;
    }
}


int main( int argc, const char** argv )
{

    VideoCapture cap;
    cap.open(1);

    if( !cap.isOpened() )
    {
        cout << "***Could not initialize capturing...***\n";
        cout << "Current parameter's value: \n";
        return -1;
    }

    namedWindow( "CamShift Demo",1 );
    
    selection = Rect(300,300,100,160);
    Mat frame, cp_roi;
    bool paused = false;
	int cnt = 0;
    for(;;)
    {
		cap >> frame;
	//	cout << "frame.cols:"<< frame.cols << endl;
	//	cout << "frame.rows:"<< frame.rows << endl;


        frame.copyTo(image);
	Mat roi(frame,selection);

        rectangle(image, Point(selection.x, selection.y), Point(selection.x + selection.width, selection.y + selection.height), Scalar(255, 0, 0), 3, 8);
	 char c = (char)waitKey(10);
		if(c=='s')
		{
			roi.copyTo(cp_roi);
			resize(cp_roi,cp_roi,Size(20,30));
			char filename[30];
			sprintf_s(filename,"../positive/%d.bmp",cnt);
			cv::imwrite(filename,cp_roi);
			cnt++;
		}

        imshow( "CamShift Demo", image );
		
       
        if( c == 27 )
            break;
       
    }

    return 0;
}
2)利用訓練好的分類器進行檢測的程式碼:
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** Function Headers */
void detectAndDisplay( Mat frame );

/** Global variables */
//-- Note, either copy these two files from opencv/data/haarscascades to your current folder, or change these locations
String face_cascade_name = "cascade_LBP_Stages20.xml";
CascadeClassifier face_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);

/**
 * @function main
 */
int main( void )
{
  VideoCapture capture;
  Mat frame;

  //-- 1. Load the cascades
  if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
 

  //-- 2. Read the video stream
  capture.open( 1 );
  if( capture.isOpened() )
  {
    for(;;)
    {
      capture >> frame;

      //-- 3. Apply the classifier to the frame
      if( !frame.empty() )
       { detectAndDisplay( frame ); }
      else
       { printf(" --(!) No captured frame -- Break!"); break; }

      int c = waitKey(10);
      if( (char)c == 'c' ) { break; }

    }
  }
  return 0;
}

/**
 * @function detectAndDisplay
 */
void detectAndDisplay( Mat frame )
{
   std::vector<Rect> faces;
   std::vector<Rect> faces2;
   Mat frame_gray;

   cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
 
   //-- Detect faces
   face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE|CV_HAAR_FIND_BIGGEST_OBJECT, Size(60, 90),Size(160, 240) );
   
   for( size_t i = 0; i < faces.size(); i++ )
    {
      Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
      ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar( 255, 0, 0 ), 3, 8, 0 );

    }

   //-- Show what you got
   imshow( window_name, frame );
}



相關推薦

應用OpenCV檢測定義目標

最近做了一個目標檢測的應用,通過大量的待檢測目標的樣本進行訓練,得到分類器;然後輸入測試視訊,看分類器的檢測結果。主要應用了OpenCV自帶的工具:1.opencv\build\x86\vc10\bin下的opencv_createsamples.exe2.opencv\bu

YOLO訓練定義目標檢測

YOLO是強大的目標檢測開源庫 ,目前支援多個類別的目標檢測,如自行車、人、動物、標識等,檢測速度比較快,V2下檢測速度在普通顯示卡上可以實時對視訊流目標檢測,雖然對小目標效果欠佳,但是大多數應用下還是有實際應用意義。相關詳細介紹可以參考:https://pjr

Confluence 6 升級定義的站點和空間應用你的定義布局

Confluence當你升級你的 Confluence 到其他一個主要的 Confluence 發行版本的時候,你需要手動應用你修改過的任何全局或者空間級別的布局。除非有特殊的聲明,針對一些非主要的 Confluence 升級,你的自定義修改應該是不需要重新應用上去的。什麽是主要版本,什麽是非主要版本?主要版

OpenCv-C++-定義角點檢測器(shi-tomashi定義

前面學過了自定義角點檢測器(Harris),現在學習tomasi自定義角點檢測,總體上來說tomasi的程式碼計算量比較harris少,具體步驟跟harris自定義角點檢測類似,主要少了"計算響應"(在部落格自定義角點檢測器(harris自定義)的程式碼註釋裡)的那一步,主要使用corner

OpenCv-C++-定義角點檢測器(harris定義

學習了前面的harris角點檢測之後,現在利用harris原理來自定義角點檢測器,主要使用cornerEigenValsAndVecs()函式。 參考:https://blog.csdn.net/weixin_41695564/article/details/79979784 該函式引數解釋

opencv-015 定義線性濾波

自定義線性濾波 l卷積概念 l常見運算元 l自定義卷積模糊 l程式碼演示 卷積概念 l卷積是影象處理中一個操作,是kernel在影象的每個畫素上的操作。 lKernel本質上一個固定大小的矩陣陣列,其中心點稱為錨點(anchor point) 卷積如何工作

使用SSD模型檢測目標

SSD簡介 SSD(Single Shot MultiBox Detector)是深度學習領域一種新型的目標檢測演算法。在過去的幾次國際比賽中,SSD在速度和準確性方面均取得優異成績,與其他檢測演算法一度拉開很大差距。 SSD的演算法流程大體可以概括為產生候

在Android應用中使用定義證書的HTTPS連線(下)

因為這部分才是本文的重點,要說得詳細一點,所以單獨做成一篇來說。安全地使用自定義證書的HTTPS連線方式終極解決方案是:把證書編譯到應用中去,由應用自己來驗證證書。生成KeyStore要驗證自定義證書,首先要把證書編譯到應用中去,這需要JSSE提供的keytool工具來生成K

C# Windows應用窗體使用者定義控制元件--開關實現

先準備了兩個好看的開關圖片: 將圖片資源匯入專案 開啟Properties下Resources.rex: 選擇影象: 新增現有檔案:(將準備好的圖片新增) 新增完成,可以看到多了一個Resources資料夾,裡面就是我們剛剛新增的圖

如何在Vim+Ctags+Taglist應用中新增定義語言: systemverilog

確切的應該是轉載別人的,然後修改的: 如何在Vim+Ctags+Taglist應用中新增自定義語言  Vim+Ctags+Taglist的應用是一個非常方便的解決方案,網路上關於這樣的簡單介紹數不勝數,只要願意不妨搜尋一下即可。 但是有一個問題是大多數文章沒有闡明的,那就是

Confluence 6 升級定義的站點和空間應用你的定義佈局

當你升級你的 Confluence 到其他一個主要的 Confluence 發行版本的時候,你需要手動應用你修改過的任何全域性或者空間級別的佈局。除非有特殊的宣告,針對一些非主要的 Confluence 升級,你的自定義修改應該是不需要重新應用上去的。 什麼是主要版本,什麼是非主要版本?主要版本的的升級主要

Android靜態安全檢測 -> 定義許可權的保護級別

自定義許可權的保護級別 - protectionLevel屬性 一、Manifest檔案中許可權相關的知識 1. <uses-permission>標籤 【1】語法定義 【2】屬性

在Android應用中使用定義證書的HTTPS連線(上)

對於初次接觸https有一定的幫助,本文屬於轉載篇。 原文地址:http://blog.csdn.net/raptor/article/details/18896375 前言 由於移動裝置使用的網路環境各種各樣,而且常常接入不安全的公共WIFI——如果你對公共WIFI

SSD-Tensorflow 目標檢測定義資料集(VOC2007格式))

一、準備 搭建SSD框架,下載解壓即可 下載pascalvoc資料,自己的資料根據voc格式改寫(圖片的名稱,不用拘泥於6位數字,其他命名也可以)資料集下載點選 解壓後不要混合在一個資料夾下 VOCtrainval用來訓練,VOCtest用來測試。 VOCtrai

opencv-定義harris角點檢測

程序 number 是什麽 val input lsa key oid tps opencv-自定義harris角點檢測 關於harris角點檢測的原理以及matlab版本,請移步https://www.cnblogs.com/klitech/p/5779600.html

xgboost 定義評價函數(metric)與目標函數

binary ret and 參數 cnblogs from valid ges zed 比賽得分公式如下: 其中,P為Precision , R為 Recall。 GBDT訓練基於驗證集評價,此時會調用評價函數,XGBoost的best_iteration和

IOS xib在tableview上的簡單應用(通過xib定義cell)

make aso eat 常用 last creat path ins div UITableView是一種常用的UI控件,在實際開發中,由於原生api的局限,自定義UITableViewCell十分重要,自定義cell可以通過代碼,也可以通過xib。 這篇隨筆介紹的是通過

每天一個JS 小demo之定義滾動條。主要知識點:事件應用

prevent 數據 滾動 sca listener 視頻 希望 特效 poi <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>D

【.net 深呼吸】定義應用程序配置節

system 深呼吸 進行 eve none 價值 判斷 發現 debug 實際上,應用程序配置文件 App.config,是由各個節(Configuration Section)組成的,通常,配置節是按功能劃分的,比如我們很熟悉的 appSettings、connecti

使用釘釘定義應用的方式實現zabbix報警

zabbix 釘釘 自定義應用 先給大家展示一下完成後的效果圖下面我們就按照下面的步驟來實現我們想要的效果首先去釘釘後臺管理添加自定義應用,關於如何創建自定義應用可以咨詢釘釘客服或者查看釘釘相關文檔,創建好應用後我們需要獲取三個信息:AgentID:創建好應用後再點擊應用進去就可以查看CorpId