[컴퓨터비전 STUDY / KOCW 한동대학교 황성수 교수님 강의 Review]
HoG란 Histogram of Oriented Gradients를 의미한다.
다시 말해, 각 pixel에 대한 gradient 값 (방향)을 표기해놓은 것이다.
이것은 openCV에서 사용될 수 있다.
다음과 같이 HoG가 생성된다.
보행자는 다음과 같이 8등분으로 나누어서 HoG를 사용할 수 있다.
Support Vector Machine은 openCV에서 사용되며, 두 개의 class를 나누는데에 사용되는 기법이다.
진한 파랑색 원은 보행자 영상에서 추출한 HoG 벡터이며, 색이 채워져 있지 않은 원은 보행자 영상이 아닌 클래스이다.
참고로, margin이 더 클수록 SVM의 성능이 더 좋다고 할 수 있다.


균등한 크기의 영역으로 나누어, Histogram normaliztion을 진행한다.
Histogram Normalization은 삐죽삐죽한 cumulative histogram 사이의 간격들을 균등하게 만드는 것을 말한다.
히스토그램의 모든 값을 더하면 1이 된다.

이미지 피라미드를 다중 스케일 감지에 사용한다.
이미지 피라미드
동일한 이미지를 해상도와 스케일에 따라 나눈 이미지 세트를 이미지 피라미드라고 한다.
원본 이미지가 있고, 단계가 높아질수록 이미지 해상도고 줄고 스케일이 커지기 때문에 이것을 스택처럼 쌓으면, 마치 피라미드와 같게 된다.
HOGDescriptor은 pedestrian detection을 위해 흔히 사용되는 함수 중 하나이다.
다시 말해, 이미지 내에서 local gradient 방향의 분포를 특징으로 사용하여 객체의 모양을 파악하는 방법이다.
size(48, 96)은 검출 윈도우 크기 (탐지하고자 하는 객체의 크기를 의미)
size(16, 16)은 블록 크기 (local gradient histogram을 계산하는 단위)
size(8, 8)은 셀 크기 (gradient 방향의 histogram을 계산하는데 사용되는 픽셀의 그룹)
9는 방향 histogram의 bin 수이다. (한 셀 내에서 gradient 방향을 얼마나 세밀하게 구분할 것인지를 나타냄)
hog.setSVMDetector은 이전에 계산한 HOGDescriptor을 이용해 기존의 학습된 data를 받아올 수 있다.
HOGDescriptor hog(Size(48, 96), Size(16, 16), Size(8, 8), Size(8, 8), 9);
hog.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector());
hog.detectMultiScale은 HOG를 이용하여 이미지에서 여러 크기의 객체를 검출하는데 사용된다.
frame : Input 이미지로써, openCV에서는 Mat 객체로 표현됨
found : 검출된 객체의 위치와 크기를 저장하는데 사용되는 직사각형 배열
1.2는 스케일 인수 (검색 윈도우의 크기를 얼마나 변경하면서 검출을 수행할지 결정함)
size(8, 8)은 윈도우 stride (검색 윈도우가 이미지를 통해 이동하는 간격을 의미함)
size(32, 32)은 패딩 크기 (검출 윈도우 주변에 추가적인 패딩을 적용하여 검출 영역을 확장 할 수 있음)
1.05는 각 검출 윈도우마다 스케일을 변경하는 비율 (이 값으로 스케일이 조절되면서 다양한 크기의 객체를 더 잘 검출할 수 있음)
6은 그룹 임계값 (같은 객체로 간주될 수 있는 검출된 직사각형의 최소 개수를 의미함)
hog.detectMultiScale(frame, found, 1.2, Size(8, 8), Size(32, 32), 1.05, 6);
아래의 코드는 동영상 파일에서 보행자를 감지하는 역할을 수행하는 코드이다.
Mat frame;
vector<Rect> found;
int i;
char ch;
// openthevideofile
VideoCapturecap("pedestrian.avi");
if (!cap.isOpened()) {
cout<< "can'topenvideofile" << endl;
return0;
}
// detector (48x96 template)
HOGDescriptorhog( // HOG 객체를 사용하여 보행자 감지
Size(48, 96),
Size(16, 16),
Size(8, 8),
Size(8, 8),
9);
// 보행자 검출기를 SVM 검출기로 설정함
hog.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector());
아래의 코드는 비디오 스트림에서 보행자를 감지하고, 감지된 보행자 주변에 경계 상자를 그리며, 그 결과를 실시간으로 표시하는 과정을 구현한다.
while(1) {
// input image 비디오의 모든 프레임을 처리함
cap>> frame; // 다음 프레임을 읽어 frame 변수에 저장함
if (frame.empty()) break;
// detect
hog.detectMultiScale( // 현재 프레임 내 보행자를 검출함
frame, // 현재 처리 중인 이미지
found, // 감지된 객체의 사각형이 저장될 벡터
1.2, // 윈도우 스케일 변화량
Size(8, 8), // 블록 stride
Size(32, 32), // 탐지 윈도우 최소 크기
1.05, // 각 이미지 스케일에서의 스케일 계수
6); // 그룹화하여 사용될 임계값
// drawresults (boundingboxes) 바운딩 박스 표시
for (i= 0; i< (int)found.size(); i++)
rectangle(frame, found[i], Scalar(0, 255, 0), 2);
// display 수정된 프레임을 PedestrianDetection 창에 표시함
imshow("PedestrianDetection", frame);
ch = waitKey(10);
if (ch == 27) break; // ESC Key
elseif (ch == 32) // SPACE Key
{
while((ch = waitKey(10)) != 32 && ch != 27);
if (ch == 27) break;
}
}
결과는 다음과 같다.
