OpenCV에 포함되어 있는 기본적인 HOG 특징을 뽑아주는 함수이다.
기본 사람검출을 위한 파라미터를 이용해서 간단한 테스트만 해봤다.
나중에 이걸 쓸일이 있을지는 모르겠지만 일단 저장..
아마 다음에 hog를 쓴다면 아마 구현해서 쓰겠지...
- Mat img;
- img = imread( "C:\\Users\\Administrator\\Pictures\\test.jpg" );
- HOGDescriptor hog;
- hog.setSVMDetector( HOGDescriptor::getDefaultPeopleDetector() );
- vector<Rect> detected;
- double time = double( GetTickCount() );
- hog.detectMultiScale( img, detected, 0, Size(9,9), Size(26,20), 1.05, 2 );
- time = double( GetTickCount() ) - time;
- int detectedCNT = detected.size();
- for( int i=0; i<detectedCNT; i++ )
- {
- Rect people = detected[i];
- rectangle( img, people, Scalar(0,0,255), 2 );
- }
- imshow( "Result", img )
그래도 별다른 작업없이 기본 파라미터만 이용해서
사검출 결과가 나오니 간단한 테스트용으로는 사용 할 만 하겠지?
아래사진은 작년 경주에서 찍은 사진.. 옆에 형은 초상권.. 으로인한 모자이크 처리 해드립니다.
성능은 뭐 예상대로 별로다. 어거지로 끼워 맞춘 느낌..
아래는 외국사이트에서 본 hog feature 시각화해서 보여주는 소스란다.
아직 확인은 안해봤지만 나중에 참고하도록 하자.
// HOGDescriptor visual_imagealizer // adapted for arbitrary size of feature sets and training images Mat get_hogdescriptor_visual_image(Mat& origImg, vector<float>& descriptorValues, Size winSize, Size cellSize, int scaleFactor, double viz_factor) { Mat visual_image; resize(origImg, visual_image, Size(origImg.cols*scaleFactor, origImg.rows*scaleFactor)); int gradientBinSize = 9; // dividing 180° into 9 bins, how large (in rad) is one bin? float radRangeForOneBin = 3.14/(float)gradientBinSize; // prepare data structure: 9 orientation / gradient strenghts for each cell int cells_in_x_dir = winSize.width / cellSize.width; int cells_in_y_dir = winSize.height / cellSize.height; int totalnrofcells = cells_in_x_dir * cells_in_y_dir; float*** gradientStrengths = new float**[cells_in_y_dir]; int** cellUpdateCounter = new int*[cells_in_y_dir]; for (int y=0; y<cells_in_y_dir; y++) { gradientStrengths[y] = new float*[cells_in_x_dir]; cellUpdateCounter[y] = new int[cells_in_x_dir]; for (int x=0; x<cells_in_x_dir; x++) { gradientStrengths[y][x] = new float[gradientBinSize]; cellUpdateCounter[y][x] = 0; for (int bin=0; bin<gradientBinSize; bin++) gradientStrengths[y][x][bin] = 0.0; } } // nr of blocks = nr of cells - 1 // since there is a new block on each cell (overlapping blocks!) but the last one int blocks_in_x_dir = cells_in_x_dir - 1; int blocks_in_y_dir = cells_in_y_dir - 1; // compute gradient strengths per cell int descriptorDataIdx = 0; int cellx = 0; int celly = 0; for (int blockx=0; blockx<blocks_in_x_dir; blockx++) { for (int blocky=0; blocky<blocks_in_y_dir; blocky++) { // 4 cells per block ... for (int cellNr=0; cellNr<4; cellNr++) { // compute corresponding cell nr int cellx = blockx; int celly = blocky; if (cellNr==1) celly++; if (cellNr==2) cellx++; if (cellNr==3) { cellx++; celly++; } for (int bin=0; bin<gradientBinSize; bin++) { float gradientStrength = descriptorValues[ descriptorDataIdx ]; descriptorDataIdx++; gradientStrengths[celly][cellx][bin] += gradientStrength; } // for (all bins) // note: overlapping blocks lead to multiple updates of this sum! // we therefore keep track how often a cell was updated, // to compute average gradient strengths cellUpdateCounter[celly][cellx]++; } // for (all cells) } // for (all block x pos) } // for (all block y pos) // compute average gradient strengths for (int celly=0; celly<cells_in_y_dir; celly++) { for (int cellx=0; cellx<cells_in_x_dir; cellx++) { float NrUpdatesForThisCell = (float)cellUpdateCounter[celly][cellx]; // compute average gradient strenghts for each gradient bin direction for (int bin=0; bin<gradientBinSize; bin++) { gradientStrengths[celly][cellx][bin] /= NrUpdatesForThisCell; } } } cout << "descriptorDataIdx = " << descriptorDataIdx << endl; // draw cells for (int celly=0; celly<cells_in_y_dir; celly++) { for (int cellx=0; cellx<cells_in_x_dir; cellx++) { int drawX = cellx * cellSize.width; int drawY = celly * cellSize.height; int mx = drawX + cellSize.width/2; int my = drawY + cellSize.height/2; rectangle(visual_image, Point(drawX*scaleFactor,drawY*scaleFactor), Point((drawX+cellSize.width)*scaleFactor, (drawY+cellSize.height)*scaleFactor), CV_RGB(100,100,100), 1); // draw in each cell all 9 gradient strengths for (int bin=0; bin<gradientBinSize; bin++) { float currentGradStrength = gradientStrengths[celly][cellx][bin]; // no line to draw? if (currentGradStrength==0) continue; float currRad = bin * radRangeForOneBin + radRangeForOneBin/2; float dirVecX = cos( currRad ); float dirVecY = sin( currRad ); float maxVecLen = cellSize.width/2; float scale = viz_factor; // just a visual_imagealization scale, // to see the lines better // compute line coordinates float x1 = mx - dirVecX * currentGradStrength * maxVecLen * scale; float y1 = my - dirVecY * currentGradStrength * maxVecLen * scale; float x2 = mx + dirVecX * currentGradStrength * maxVecLen * scale; float y2 = my + dirVecY * currentGradStrength * maxVecLen * scale; // draw gradient visual_imagealization line(visual_image, Point(x1*scaleFactor,y1*scaleFactor), Point(x2*scaleFactor,y2*scaleFactor), CV_RGB(0,0,255), 1); } // for (all bins) } // for (cellx) } // for (celly) // don't forget to free memory allocated by helper data structures! for (int y=0; y<cells_in_y_dir; y++) { for (int x=0; x<cells_in_x_dir; x++) { delete[] gradientStrengths[y][x]; } delete[] gradientStrengths[y]; delete[] cellUpdateCounter[y]; } delete[] gradientStrengths; delete[] cellUpdateCounter; return visual_image; }
'Programming > OpenCV' 카테고리의 다른 글
jpeg 파일 디코딩하기. (0) | 2015.11.11 |
---|---|
unsigned char* 형 버퍼를 IplImage 또는 Mat 으로 변환하기. (0) | 2014.08.18 |
[Function] 영상을 회전 시키기 (0) | 2014.01.23 |
[Function] IplImage 에 한글text 삽입하기 (1) | 2013.11.07 |
DC -> IplImage로 전환 (0) | 2013.08.08 |