본문 바로가기
ੈ✩‧₊˚Computer Science/컴퓨터비전

[OpenCV] Pedestrian detection (보행자 검출)

by 샨샨 2020. 11. 18.
반응형

OpenCv에서 보행자 검출은 Hog를 이용한다.

 

- Hog : 각 픽셀에 대한 gradient 값을 히스토그램으로 계산한 것 (gradient : x,y 의 미분값)

- 주어진 보행자 영상에서 영역을 분할하고 각각의 영역에 대해 HoG를 계산한 다음 HoG값을 이어 붙인다.(concatenation)

- HoG가 보행자를 표현하기에 좋은 feature라면 보행자 concatenation 과 아닌 것의 차이가 있을 것이다.

 

- Support Vector Machine(SVM)를 이용해 두개의 class를 구분하는 선 (classifier)을 생성 ☞ SVM을 이용해 training 

- 파란색원이 보행자, 비어있는 원이 보행자가 아닌 영상 표현

- margin이 클수록 좋다 ( margin : 가장 가까운 원과 원사이의 간격)

이미지 전처리/후처리

- Image resizing : 다양한 크기의 보행자가 있을 수 있기 때문에 image 를 resizing 

- Block normalization : 이미지 Normalization (빛의 크기에 따라 달라지는 것을 극복)

왼 : 이미지 크기 재설정 오 : 이미지 normalization

 

OpenCV 보행자 검출 함수

HOGDescriptor::HOGDescriptor ( Size _winSize, Size _blockSize, Size _blockStride, Size _cellSize, int _nbins, int _derivAperture = 1, double _winSigma = -1, int _histogramNormType = HOGDescriptor::L2Hys, double _L2HysThreshold = 0.2, bool _gammaCorrection = false,
int _nlevels = HOGDescriptor::DEFAULT_NLEVELS, bool _signedGradient = false  )

▨ winSize : detection을 위해 사용하는 window 크기

▨ blockSize : 하나의 block의 크기 (16 X 16 만 제공됨)

▨ blockStride : block 내에서 히스토그램 normalization을 위한 값 ( Cellsize의 정수배가 되어야함)

▨ cellSize : block내의 조그마한 cell 크기 (현재 8 X 8만 제공됨)

▨ nbins : HOG 계산 할 때 사용하는 bin 의 개수 ( 현재 9만 가능)

☞ 나머지는 대부분 초기값 이용

 

void cv::HOGDescriptor::detectMultiScale( InputArray img, std::vector<Rect> & foundLocations, double hitThreshold =0, Size winStride = Size(), Size padding = Size(), double scale = 1.05, double finalThreshold = 2.0, bool useMeanshiftGrouping = false const)

▨ img : input image

▨ foundLocations : 보행자를 인식한 사각형 (결과)

▨ hitThreshold : 크게 설정하면, 식별기 주위에 있는 영상은 보행자가 아니라고 판단 (클수록 검출 수 낮아짐, 정확도 높아짐)

▨ winStride : 이미지 패치를 생성해내는 간격

▨ padding : 영상의 가장자리에서 block이 제대로 생성이 안되는 경우 사용 (별로 안중요함)

▨ scale: 다양한 크기의 보행자 검출을 위해 존재, 이 값이 크면 듬성듬성 검출되기 때문에 보행자 검출 수가 낮아짐, 속도 빨라짐

▨ group_threshold : 검출이 중복해서 나오는 경우, 설정한 개수 이상일 때 그룹화함

 

 

보행자 검출 예제 코드

#include "cv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(){
    Mat frame;
    vector <Rect> found;
    int i;
    char ch;

    VideoCapture cap("../Week12/pedestrian.mp4");

    if(!cap.isOpened()){
        cout << "can't open video file" << endl;
        return 0;
    }

    HOGDescriptor hog(
        Size(48,96),
        Size(16,16),
        Size(8,8),
        Size(8,8),
        9
    );

    while(1){
        cap >> frame;
        if(frame.empty()) break;

        hog.detectMultiScale(
            frame,
            found,
            1.2,
            Size(8,8),
            Size(32,32),
            1.05,
            6
        );

        hog.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector());

        for(i=0; i<(int)found.size();i++){
            rectangle(frame,found[i],Scalar(0,255,0),2);
        }

        imshow("pedestrian detection",frame);
        ch = waitKey(10);
        if(ch ==27) break;
        else if(ch ==32){
            while((ch = waitKey(10) !=32 && ch!=27));
            if(ch==27) break;
        }
    }
}

 

결과 화면

 

반응형