亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實現基于opencv的行人檢測

發布時間:2021-12-22 12:42:23 來源:億速云 閱讀:199 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“如何實現基于opencv的行人檢測”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“如何實現基于opencv的行人檢測”這篇文章吧。

基于方向梯度直方圖(HOG)/線性支持向量機(SVM)算法的行人檢測方法中存在檢測速度慢的問題,如下圖所示,對一張400*490像素的圖片進行檢測要接近800毫秒,所以hog+svm的方法放在視頻中進行行人檢測時,每秒只能檢測1幀圖片,1幀/s根本不能達到視頻播放的流暢性。

如何實現基于opencv的行人檢測

本文采用先從視頻每幀的圖像中提取出物體的輪廓(也可以對前后兩針圖片做差,只對有變化的部分進行檢測,其目的一樣,都是減少運算的面積),再對每個輪廓進行HOG+SVM檢測,判斷是否為行人。可以大大的縮減HOG+SVM的面積,經實測,檢測速度可以達到10幀/S,可以勉強達到視頻流暢的要求。

輪廓的提取用的是cv::findContours的API,感興趣的可以自己去查看相關資料

首先介紹下方向梯度直方圖。

在圖像或者視頻幀中,邊緣方向密度分布可以很好地描述局部目標的形狀和表象,也就是說通過 HOG特征,可以有效地將人體和復雜背景區分出來。對于行人檢測中 HOG 特征提取的具體實現方法是: 將視頻中的每一幀通過滑動窗口切割成很小的區域( Cell) ,通過計算每個區域面的方向梯度特征,得到每個區域的方向特征直方圖,小區域再組成更大的區域,通過將區域的方向梯度特征組合起來并在塊單元中進行歸一化處理,就形成了一個 Block 內 HOG 描述子,遍歷搜索所有的方向特征從而最終構成一個幀的 HOG 描述特征向量。算法的過程[3]分為:

①將一個視頻的每一幀進行灰度化處理。把視頻的每一幀彩色空間變成灰度空間,因為 HOG 中不需要彩色信息的幫助。

②對輸入的視頻的每一幀進行顏色空間的歸一化。由于視頻中人信息的復雜性,背影的灰暗程度以及光照的影響都對檢測器的魯棒性有一定的影響,歸一化可以很大程度上降低這些的影響。這 里 使 用gamma 校正: 對像素值求其平方根( 降低數值大小) 。

③計算像素梯度。這是 HOG 特征檢測中最重要的一個環節,通過像素的梯度方向直方圖來描述像素的特征。特別注意的是我們不需要做平滑處理,因為平滑處理的本質就是迷糊圖像,降低了像素邊緣信息,因而就不能很好地提取邊緣信息來表達特征。

④將圖像劃分成小 cell。這一步我們需要為計算梯度,建立梯度方向直方圖定義一個載體,因此這里把圖像分割成很小的區域,這里稱為細胞單元,實驗表明6 × 6 像素的細胞單元效果最佳。接著采用 9 個直方圖來統計一個細胞單元里面的特征信息。360°不考慮
正負方向,把方向分成 9 份,如圖 1 所示,稱為 bin,也就是每一個 bin 對應 20°,這樣就把梯度方向映射到直方圖里面,9 個方向特征向量代表 9 個 bin,增幅就代表每一個 bin 的權值。

⑤統計每個 cell 的梯度直方圖即可形成每個 cell的 descriptor。

⑥將每幾個 cell 組成一個 block,一個 block 內所有 cell 的特征串聯起來,便得到該 block 的 HOG 特征descriptor。

⑦將圖像內所有 block 的 HOG 特征收集起來就可得到該圖像特征向量。

支持向量機

支持向量機( Support Vector Machine) 就是風險降低到最小程度上,尋找最優的解決方案。視頻檢測特征分類中,就是針對低維空間的線性不可分問題,通過核函數映射到高維空間達到線性可分,再進行線性分割實現特征分類。
SVM 具有以下幾個特點:
( 1) 小樣本。
( 2) 非 線 性 問 題。即針對線性的不可分問題,SVM 通過松弛變量以及核函數進行解決。
( 3) 高維模式識別。在某些樣本,例如密集型特征,可以達到幾萬甚至十幾萬的維數,如果不對樣本進行降維,SVM 也能夠找出支持向量樣本,對這些特征訓練出優秀的分類器。

視頻檢測代碼:

void video_test() {
	void display(Mat, vector<Rect>&);            
	//void Crop_picture();     
	//void train();
	//void save_hard_example();
	
	//Crop_picture();     //裁切負樣本圖片,每張負樣本圖片隨機裁成10張
	//train();          //訓練正負樣本
	//save_hardexample()     //根據正負樣本得到的檢測子,對INRIAPerson/Train/neg/中的圖片進行測試,并將錯檢的樣本保存
	//train();      //訓練正負樣本及難例樣本
	
 
	//加載svm分類器的系數
	HOGDescriptor hog; string str;
	vector<float> detector;
	/*ifstream fin("HOGDetectorForOpenCV.txt");
	while (getline(fin, str))
	{
		detector.push_back(stringToNum<float>(str));
	}
*/
 
	vector<Rect> people;
	VideoCapture capture(VideotestPath);
	/*if (!capture.isOpened())
	return -1;*/
	Mat frame, foreground;
	
 
	int num = 0; 
	Ptr<BackgroundSubtractorMOG2> mod = createBackgroundSubtractorMOG2();
 
	while (true)
	{
		vector<Rect> rect6;
		if (!capture.read(frame))
		break;
		mod->apply(frame, foreground, 0.01);
		hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
		//hog.setSVMDetector(detector);
		vector<Rect> rect5;
		display(foreground, rect5);
		vector<Rect> ret = rect5;
		for (auto i = 0; i != ret.size(); i++)
		{
			Mat a = frame;
		
 
			if (ret[i].x > 50 && ret[i].y > 50 && ret[i].x + ret[i].width <670 && ret[i].y + ret[i].height < 520)
			{
				ret[i].x = ret[i].x - 50;
				ret[i].y = ret[i].y - 50; ret[i].width = ret[i].width + 100; ret[i].height = ret[i].height + 100;
			}
			Mat src(a(ret[i]));
			cout << ret[i].x << " " << ret[i].y << " " << ret[i].width << " " << ret[i].height << endl;
			// imshow("aa", src); waitKey(0);
			// cv::namedWindow("src", CV_WINDOW_NORMAL); 
 
 
 
			if (ret[i].width >= 64 && ret[i].height >= 128)
 
				hog.detectMultiScale(src, people, 0, Size(4, 4), Size(0, 0), 1.07, 2);
			//cout << people.size()<<endl;
			for (size_t j = 0; j < people.size(); j++)
			{
				people[j].x += ret[i].x; people[j].y += ret[i].y;
				rect6.push_back(people[j]);
				//rectangle(frame, people[j], cv::Scalar(0, 0, 255), 2);
			}
			//imshow(" ", frame); waitKey(0);
 
		}
		//因為多尺度檢測得到的結果矩形框較大,按比例縮減矩形框
		for (auto h = 0; h != rect6.size(); h++)
		{
			rect6[h].x += cvRound(rect6[h].width*0.1);
			rect6[h].width = cvRound(rect6[h].width*0.8);
			rect6[h].y += cvRound(rect6[h].height*0.07);
			rect6[h].height = cvRound(rect6[h].height*0.8);
			rectangle(frame, rect6[h], cv::Scalar(0, 0, 255), 1);
			//rect2[h] = boundingRect(frame);
		}
		imshow(" ", frame); waitKey(1);
	}
	waitKey();
}

提取輪廓的代碼:

void display(Mat gray_diff, vector<Rect>& rect)
{
	//Mat res = src.clone();
	vector<vector<Point>> cts;  //定義輪廓數組
	findContours(gray_diff, cts, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //查找輪廓,,模式為只檢測外輪廓,并存儲所有的輪廓點
																		  //vector<Rect> rect; //定義矩形邊框
	for (int i = 0; i < cts.size(); i++)
	{
		if (contourArea(cts[i])>th_area)       //計算輪廓的面積,排除小的干擾輪廓
			
			  //查找外部矩形邊界  
			rect.push_back(boundingRect(cts[i]));   //計算輪廓的垂直邊界最小矩形
 
	}
	cout << rect.size() << endl;     //輸出輪廓個數
}

檢測效果:

如何實現基于opencv的行人檢測

進行HOG+SVM的四個頂點像素坐標。可以看到每次運算的面積小了很多。

如何實現基于opencv的行人檢測

當然 ,是可以優化,比如每兩幀圖片檢測一次,下一幀圖片保持上一幀的檢測結果。比如輪廓區域的面積怎么去合適的框起來,如何設定合適的閾值去濾掉小框,兩個框重疊時,怎么去優化,減小進行運算的面積。本文只是給個思路,具體讀者可以自己去實現。

以上是“如何實現基于opencv的行人檢測”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湘潭市| 安庆市| 吐鲁番市| 八宿县| 闻喜县| 兴义市| 文水县| 鹤庆县| 吉安市| 布尔津县| 冕宁县| 姜堰市| 邛崃市| 莎车县| 聊城市| 芦山县| 右玉县| 勃利县| 长葛市| 天津市| 龙口市| 绥德县| 大名县| 嵊州市| 湘乡市| 通渭县| 南投县| 芷江| 怀安县| 大埔区| 娱乐| 会理县| 西乌珠穆沁旗| 兴文县| 安陆市| 嘉鱼县| 大庆市| 兴仁县| 达尔| 凤城市| 三明市|