1. 程式人生 > >Cascade Latent-SVM -base opencv3.0 beta

Cascade Latent-SVM -base opencv3.0 beta

前言

研究DPM需要深入閱讀下述兩篇文獻:
《2009 Object Detection with Discriminatively Trained Part Based Models》
《2010 Cascade Object Detection with Deformable Part Models》

github上的兩個版本的程式碼,matlab版本的,win/linux;ffld版本的程式碼已經安裝執行,而且介紹了一款矩陣開源庫-eigen;包含了大多數矩陣運算操作,C++實現,很喜歡!只是淺略的運行了兩個例程;言歸正傳,ffld依然只提供了使用已知模型txt進行檢測,其提供了檢測自行車的模型,沒有其他的如行人/車的模型;需要使用matlab版本進行訓練;
程式碼只是淺略的學習了一下,主要演算法流程:
訓練:
1.計算金字塔影象,hog特徵(PCA降維)
2.滑動視窗檢測每一塊的score,選擇最高分的尺度和位置;
3.隱藏引數以及其他的型別,進行區分;
4.提取根區和子區
測試:
1.計算金字塔影象,hog特徵
2.分別執行根區和子區濾波至hog特徵矩陣,累加計算得分;
3.應用閾值法,最高得分是否超出閾值,從而確定是否為待檢測區域;

可見,Latent SVM和座標下降法/梯度下降法主要用於訓練;

1. 測試

1.1 建立工程

test_latentsvmdetector_cascade.cpp

test_main.cpp

test_precomp.cpp

test_precomp.hpp

建立工程,第一個檔案為執行主體;

 std::string img_path_cat = std::string(ts->get_data_path()) + "cat.png";
    std::string img_path_cars = std::string(ts->get_data_path()) + "cars.png";
	std::string img_path_peoples = std::string(ts->get_data_path()) + "four_people_no.jpg";

    std::string model_path_cat = std::string(ts->get_data_path()) + "models_VOC2007_cascade/cat.xml";
    std::string model_path_car = std::string(ts->get_data_path()) + "models_VOC2007_cascade/car.xml";
	std::string model_path_people = std::string(ts->get_data_path()) + "models_VOC2007_cascade/person.xml";

	//不包含people資訊
    std::string true_res_path = std::string(ts->get_data_path()) + "results_cascade.xml";
	
	std::cout << ts->get_data_path() << std::endl;
	std::cout << std::string(ts->get_data_path()) << std::endl;

#ifdef HAVE_TBB
    int numThreads = 2;
#endif

    Mat image_cat = imread( img_path_cat );
    Mat image_cars = imread( img_path_cars );
	Mat image_peoples = imread(img_path_peoples);
	if (image_cat.empty() || image_cars.empty() || image_peoples.empty())
    {
        ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
        return;
    }

    // We will test 2 cases:
    // detector1 - to test case of one class 'cat'
    // detector12 - to test case of two (several) classes 'cat' and car

    // Load detectors
	//推薦單獨載入檢測xml
    cv::Ptr<lsvm::LSVMDetector> detector1 = lsvm::LSVMDetector::create(std::vector<std::string>(1,model_path_cat));
	cv::Ptr<lsvm::LSVMDetector> detector_people = lsvm::LSVMDetector::create(std::vector<std::string>(1, model_path_people));

    std::vector<std::string> models_pathes(3);
    models_pathes[0] = model_path_cat;
    models_pathes[1] = model_path_car;
	models_pathes[2] = model_path_people;
    cv::Ptr<lsvm::LSVMDetector> detector12 = lsvm::LSVMDetector::create(models_pathes);

    if( detector1->isEmpty() || detector12->isEmpty() || detector12->getClassCount() != 3||
		detector_people->isEmpty())
    {
        ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
        return;
    }

    // 1. Test method detect
    // Run detectors
	std::vector<lsvm::LSVMDetector::ObjectDetection> detections1_cat, detections12_cat, detections12_cars, detections12_people;
    detector1->detect( image_cat, detections1_cat, 0.5);
    detector12->detect( image_cat, detections12_cat, 0.5);
    detector12->detect( image_cars, detections12_cars, 0.5);
	detector_people->detect(image_peoples, detections12_people, 0.5);

	for (int idx_1 = 0; idx_1 < detections1_cat.size() && detections1_cat[idx_1].score>0.5; idx_1++)
	{
		rectangle(image_cat, detections1_cat[idx_1].rect, cv::Scalar(255, 0, 0));
	}
	for (int idx_2 = 0; idx_2 < detections12_cat.size() && detections12_cat[idx_2].score>0.5; idx_2++)
	{
		rectangle(image_cat, detections12_cat[idx_2].rect, cv::Scalar(0, 255, 0));
	}
	for (int idx_3 = 0; idx_3 < detections12_cars.size() && detections12_cars[idx_3].score>0.5; idx_3++)
	{
		rectangle(image_cars, detections12_cars[idx_3].rect, cv::Scalar(0, 0, 255));
	}
	for (int idx_4 = 0; idx_4 < detections12_people.size() && detections12_people[idx_4].score>0.5; idx_4++)
	{
		rectangle(image_peoples, detections12_people[idx_4].rect, cv::Scalar(0, 0, 255));
	}

簡單修改test_latentsvmdetector_cascade.cpp,對貓,人,車進行檢測,並記錄檢測的結果;

1.2 設定環境變數

在test_main.cpp中,顯示了一種模式測試執行程式碼的方式,在debug時有很多方便,所以不作修改了。但需要設定一個環境變數

OPENCV_TEST_DATA_PATH

H:/github/opencv/modules/opencv_contrib/modules/latentsvm/testdata

推薦使用路徑分割符"/"

2. 執行結果


檢測效果還是可以接受的。但需要注意檢測成績閾值的設定。

3. 訓練

已有的xml可以滿足一定的需求,但也許我們更希望訓練自己的xml,

下述論述可能有些幫助:

The MATLAB implementation of LatSVM by the authors of the paper has a train script called pascal. There is a README with the tarball explaining its usage:


Using the learning code
=======================


1. Download and install the 2006-2011 PASCAL VOC devkit and dataset.
   (you should set VOCopts.testset='test' in VOCinit.m)
2. Modify 'voc_config.m' according to your configuration.
3. Start matlab.
4. Run the 'compile' function to compile the helper functions.
   (you may need to edit compile.m to use a different convolution 
    routine depending on your system)
5. Use the 'pascal' script to train and evaluate a model. 


example:
>> pascal('bicycle', 3);   % train and evaluate a 6 component bicycle model


The learning code saves a number of intermediate models in a model cache directory defined in 'voc_config.m'.
For more information, visit the authors website. The page also contain the paper of this method.

For more information, visit the authors website. The page also contain the paper of this method.