天天看點

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 建立工程

安裝opencv3.0及opencv_contrib,以opencv_contrib/latentsvm/test下的四個檔案

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時有很多友善,是以不作修改了。但需要設定一個環境變量

Cascade Latent-SVM -base opencv3.0 beta

OPENCV_TEST_DATA_PATH

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

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

2. 運作結果

Cascade Latent-SVM -base opencv3.0 beta
Cascade Latent-SVM -base opencv3.0 beta
Cascade Latent-SVM -base opencv3.0 beta

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

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.