4/17/2014

Example source code of extract HOG feature from images, save descriptor values to xml file, using opencv (using HOGDescriptor )

This example source code is to extract HOG feature from images.
And save descriptors to XML file.

The source code explain how to use HOGDescriptor function.



..
#include < stdio.h>
#include < opencv2\opencv.hpp>
//#include < opencv2\gpu\gpu.hpp>

using namespace cv;
using namespace std;


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")         
#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing        
#pragma comment(lib, "opencv_objdetect247d.lib") //HOGDescriptor
//#pragma comment(lib, "opencv_gpu247d.lib")        
//#pragma comment(lib, "opencv_features2d247d.lib")        
#pragma comment(lib, "opencv_highgui247d.lib")        
//#pragma comment(lib, "opencv_ml247d.lib")      
//#pragma comment(lib, "opencv_stitching247d.lib");      
//#pragma comment(lib, "opencv_nonfree247d.lib");      
  
#else        
#pragma comment(lib, "opencv_core247.lib")        
#pragma comment(lib, "opencv_imgproc247.lib")        
#pragma comment(lib, "opencv_objdetect247.lib")        
//#pragma comment(lib, "opencv_gpu247.lib")        
//#pragma comment(lib, "opencv_features2d247.lib")        
#pragma comment(lib, "opencv_highgui247.lib")        
//#pragma comment(lib, "opencv_ml247.lib")        
//#pragma comment(lib, "opencv_stitching247.lib");      
//#pragma comment(lib, "opencv_nonfree247.lib");      
#endif 


void main()
{
 //variables
 char FullFileName[100];
 char FirstFileName[100]="./images/upperbody";
 char SaveHogDesFileName[100] = "Positive.xml";
 int FileNum=96;

 vector< vector < float> > v_descriptorsValues;
 vector< vector < Point> > v_locations;


 for(int i=0; i< FileNum; ++i)
 {
  sprintf_s(FullFileName, "%s%d.png", FirstFileName, i+1);
  printf("%s\n", FullFileName);

  //read image file
  Mat img, img_gray;
  img = imread(FullFileName);
  
  //resizing
  resize(img, img, Size(64,48) ); //Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) ); 
  //gray
  cvtColor(img, img_gray, CV_RGB2GRAY);

  //extract feature
  HOGDescriptor d( Size(32,16), Size(8,8), Size(4,4), Size(4,4), 9);
  vector< float> descriptorsValues;
  vector< Point> locations;
  d.compute( img_gray, descriptorsValues, Size(0,0), Size(0,0), locations);

  //printf("descriptor number =%d\n", descriptorsValues.size() );
  v_descriptorsValues.push_back( descriptorsValues );
  v_locations.push_back( locations );
  //show image
  imshow("origin", img);

  waitKey(5);
 }

 //refer to this address -> http://feelmare.blogspot.kr/2014/04/the-example-source-code-of-2d-vector.html
 //save to xml
 FileStorage hogXml(SaveHogDesFileName, FileStorage::WRITE); //FileStorage::READ
 //2d vector to Mat
 int row=v_descriptorsValues.size(), col=v_descriptorsValues[0].size();
 printf("col=%d, row=%d\n", row, col);
 Mat M(row,col,CV_32F);
 //save Mat to XML
 for(int i=0; i< row; ++i)  
  memcpy( &(M.data[col * i * sizeof(float) ]) ,v_descriptorsValues[i].data(),col*sizeof(float));
 //write xml
 write(hogXml, "Descriptor_of_images",  M);

 //write(hogXml, "Descriptor", v_descriptorsValues );
 //write(hogXml, "locations", v_locations );
 hogXml.release();

}



...


same with above code.
< gist code start>

< gist code end >


26 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. ์•ˆ๋…•ํ•˜์„ธ์š”"" ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ์กฐํ•ด์„œ Positive, Negative data๋ฅผ ๋งŒ๋“ค๊ณ  SVM tratining์„ ํ•ด๋ณด๋ ค๊ณ  ํ•˜๊ณ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์ œ๊ณตํ•ด์ฃผ์‹  ์ฝ”๋“œ๋กœ Positive.xml์€ ์ƒ์„ฑํ•ด๋ณด์•˜๋Š”๋ฐ, Negative.xml๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ•˜๋ฉด ๋˜๋Š”๊ฑด์ง€ ๊ถ๊ธˆํ•ด์„œ ์งˆ๋ฌธ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด Negative.xml์€ ์ด๋ฏธ์ง€์˜ ์ด๋ฆ„๋งŒ ์ ์–ด์ฃผ๋ฉด ๋˜๋Š”๊ฑด๊ฐ€์š”??
    ๊ทธ๋ฆฌ๊ณ , ์‚ฌ๋žŒ์„ ๊ฒ€์ถœํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด Positive.xml ์ƒ์„ฑ์‹œ์— ์‚ฌ์šฉ๋˜๋Š” ์ด๋ฏธ์ง€๋Š” ์ด๋ฏธ์ง€์—์„œ ์‚ฌ๋žŒ๋งŒ ์ž˜๋ผ์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๊ฑด๊ฐ€์š”?
    Negative ์ด๋ฏธ์ง€๋Š” ์‚ฌ๋žŒ์ด ์—†๋Š” ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ด์•ผํ•˜๊ตฌ์š”?

    ๋‘์„œ์—†์ด ์งˆ๋ฌธ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค;;

    ReplyDelete
  3. You also should make negative.xml file.
    The negative image should not contain positive image ex) face, human body...

    positive.xml have to make similar images.
    refer to this weg page" http://feelmare.blogspot.kr/search/label/Data"

    negative.xml was made by natural images not include positive images.
    and that is good way using background image of actual testing. then you can avoid false positive detection of you predicted.
    ->์‹ค์ œ ์ ์šฉํ•  ๊ณณ์˜ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ค๊ฒ€์ถœ ์˜ˆ์ƒ ๋ถ€๋ถ„์„ ์—†์•จ ์ˆ˜ ์žˆ๊ฒ ์ฃ ..

    thank you.

    ReplyDelete
  4. ์•ˆ๋…•ํ•˜์„ธ์š”.
    ๊ถ๊ธˆํ•œ์ ์ด ์ƒ๊ฒจ ์ด๋ ‡๊ฒŒ ์งˆ๋ฌธ ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
    ์œ„์— ๋ณด๋ฉด ="./images/upperbody"; ๋ถ€๋ถ„์ด ๋ฐ์ดํ„ฐ์…‹์œ„์น˜ ์ •๋ณด๊ฐ™์€๋ฐ
    ํด๋”์ธ๊ฐ€์š”???
    ์ฝ”๋”ฉ์‹œ ๊ณ„์† ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๊ณ ํ•˜๋„ค์š”
    ๋‹ต๋‹ตํ•œ๋งˆ์Œ์— ์—ฌ์ญค๋ด…๋‹ˆ๋‹ค

    ReplyDelete
    Replies
    1. ๋‹ค์ˆ˜์˜ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š” ํด๋”์—ฌ์•ผํ•˜๋Š”์ง€.. .xmlํ˜•์‹์˜ ์ž๋ฃŒ์—ฌ์•ผํ•˜๋Š”์ง€..
      ๋˜ํ•œ ์ด๋ฏธ์ง€ ์‚ฌ์ด์ฆˆ๋„ ์ƒ๊ด€์žˆ๋Š”๊ฑด์ง€... ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.
      ์ดˆ๋ณด๊ฐ€ ์ด๋Ÿฌํ•œ ์งˆ๋ฌธํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

      Delete
    2. ์ง€๊ธˆ ์†Œ์Šค๋Š” ๋‹ค์ˆ˜์˜ ์ด๋ฏธ์ง€๋ฅผ for๋กœ ๋ฃจํ”„๋Œ๋ฉด์„œ hough ํŠน์ง•์„ ์ถ”์ถœํ•˜๊ณ  ์žˆ๊ณ ์š”
      ์˜์ƒ ์‚ฌ์ด์ฆˆ๋ฅผ ๊ฐ™๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฃจํ”„์•ˆ์—์„œ resize๋ฅผ ํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
      hough ํŠน์ง•์€ ๋˜‘๊ฐ™์€ ์‚ฌ์ด์ฆˆ๋กœ ๋ฝ‘๊ณ  ๊ทธ๊ฒƒ์„ ํ•™์Šตํ• ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
      ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

      Delete
    3. "./images/upperbody"; ๋Š” ํด๋”๊ฐ€ ๋งž๊ณ ์š”
      sprintf_s(FullFileName, "%s%d.png", FirstFileName, i+1);

      ์ด ๋ฌธ์žฅ์— ์˜ํ•ด์„œ ํŒŒ์ผ๋ช…์ด ๋งŒ๋“ค์–ด ์ง‘๋‹ˆ๋‹ค.
      ๋‹ค์ˆ˜์˜ ํŒŒ์ผ์ด ์ˆœ์„œ๋˜๋กœ ์ •๋ฆฌ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

      Delete
  5. See detail in for loop.
    How to use FirstFileName char(line 47)
    And Why code use resize function(line 55)
    Increase your code reading skill.
    Cheer up!

    ReplyDelete
  6. Anonymous6/5/16 10:54

    thx for this example

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi, I wonder if there is a version of this code that can be implemented in Android studio?

    ReplyDelete
    Replies
    1. Em.. actually I don't know android environment.
      but even though android, that can load xml file, may be.
      so first make xml file on pc, and after load xml on android.
      Thank you.

      Delete
  9. Library Link Error!! Do You Kindly Share Complete Package Of Source Code

    ReplyDelete
    Replies
    1. sorry, do you meet opencv library link error?
      Do you use 2.xx version like me?
      Thank you.

      Delete
  10. ์•ˆ๋…•ํ•˜์„ธ์š”.
    ๊ถ๊ธˆํ•œ์ ์ด ์žˆ์–ด์„œ ์งˆ๋ฌธ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
    ๋งˆ์ง€๋ง‰์— hogXml.release();๋ฅผ for๋ฌธ ์•ˆ์— ๋„ฃ์œผ๋ฉด ์ €์žฅํ•  ๊ณต๊ฐ„์ด ์—†๋‹ค๋Š” error ๋ฉ”์„ธ์ง€๊ฐ€ ๋œจ๋Š”๋ฐ
    for๋ฌธ ๋ฐ–์œผ๋กœ ๊บผ๋‚ด์„œ write๋ฅผ ๋‹ค ๋๋‚ธ ํ›„์— release๋ฅผ ํ•˜๋ฉด ์•ˆ๋˜๋Š”๊ฑด์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.
    ๊ทธ๋ฆฌ๊ณ  ํ•ด๋ณธ ๊ฒฐ๊ณผ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋˜๋ฐ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š”๊ฒŒ ๋งž๋Š”๊ฑด์ง€...๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.
    ์•„์ง ๋ฐฐ์šฐ๊ณ  ์žˆ๋Š” ๋‹จ๊ณ„์—ฌ์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

    ReplyDelete
    Replies
    1. ๋ง์”€ํ•˜์‹  ๋ฐฉ๋ฒ•์ด ๋งž๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
      ์ฝ”๋“œ ๋ผ์ธ์ด ๋ณด๊ธฐ ํž˜๋“ค์–ด์„œ gist๋กœ ๋‹ค์‹œ ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค.
      ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

      Delete
  11. ์•ˆ๋…•ํ•˜์„ธ์š”. ๊ถ๊ธˆํ•œ์ ์ด ์žˆ์–ด ์งˆ๋ฌธ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
    hog.compute ํ•จ์ˆ˜๋ฅผ ์จ์„œ ์ œ๊ฐ€ ์›ํ•˜๋Š” ๊ฐ์ฒด์˜ hog ํŠน์ง•์„ ๋ฝ‘๊ณ  ํ•™์Šตํ•˜๋Š”๋ฐ ์ž˜ ์ด์šฉํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.
    ์ข€๋” ์ž์„ธํ•œ feature ๋ฅผ ๋ฝ‘๊ณ  ์‹ถ์–ด์„œ ํฌ๊ฒŒ ๋ฝ‘๊ณ  ์‹ถ์–ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์งฏ๋Š”๋ฐ์š”. ์ €์˜ ์ด๋ก ์ƒ์œผ๋กœ๋Š” ํ™•์‹คํ•œ๋ฐ ๋ญ๊ฐ€ ๋ฌธ์ œ์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”. compute ํ•จ์ˆ˜๊ฐ€ window ์‚ฌ์ด์ฆˆ์˜ limitation ์„ ๊ฑธ์–ด๋…ผ๊ฑด์ง€.. ์•„๋‹ˆ๋ฉด ์ œ๊ฐ€ ์ •๋ง ์ž˜๋ชป ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”๊ฑด์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์„œ Mare๋‹˜์˜ ๋„์›€์„ ์–ป์„์ˆ˜ ์—†์„๊นŒ ์‹ถ์–ด ์ด๋ ‡๊ฒŒ ์งˆ๋ฌธ์„ ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

    resize(mat_input, mat_input, Size(160,100));
    cvtColor(mat_input, mat_gray, CV_RGB2GRAY);
    ์ด๋ฏธ์ง€ ์‚ฌ์ด์ฆˆ๋Š” ์œ„์™€ 160,100 ์œผ๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
    //extract feature
    HOGDescriptor hogDescriptor(Size(160, 100), Size(40, 40), Size(20, 20), Size(20, 20), 9);
    vector< float> vf_DescriptorsValues;
    vector< Point> v_LocationPoint ;

    cv::Size winStride(0, 0);
    cv::Size winPadding(0, 0);
    hogDescriptor.compute(mat_gray, vf_DescriptorsValues, winStride, winPadding, v_LocationPoint);

    ์ œ๊ฐ€ ์ƒ๊ฐํ•˜๊ธฐ๋กœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •์„ ํ–ˆ์„ ๊ฒฝ์šฐ, 1008 feature dimension์ด ๋‚˜์˜ฌ๊ฒƒ์ด๋ผ ์˜ˆ์ƒํ•˜๋Š”๋ฐ,
    128,80 ๊นŒ์ง€์˜ ์œˆ๋„์šฐ ๊นŒ์ง€๋Š” ํ—ˆ์šฉ์„ ํ•˜์˜€์œผ๋‚˜, ๊ทธ ์ด์ƒ์œผ๋กœ๋Š” ๊ณ„์‚ฐ์ด ๋˜์งˆ ์•Š์Šต๋‹ˆ๋‹ค.

    ์ œ๊ฐ€ ์„ค์ •ํ•œ ์ฝ”๋“œ์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”๊ฒƒ์ธ๊ฐ€์š”? ํ™•์ธ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹คใ… ใ… 

    ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”๊ฒƒ์ด๋ฉด, ์ €๋Š” 320,200์ •๋„์˜ ์ด๋ฏธ์ง€์—์„œ hog feature๋ฅผ ๋ฝ‘๊ณ  ์‹ถ์€๋ฐ, ํ˜น์‹œ ํฐํฌ๊ธฐ์˜ ์˜์ƒ์—์„œ ๋ฝ‘๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ๊ณ„์‹ ์ง€ ์—ฌ์ญค๋ด๋„ ๋ ๊นŒ์š”?

    ReplyDelete
    Replies
    1. ๋„ค ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. hog ํŠน์ง• ์ƒ์„ฑํ• ๋•Œ, ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ข€ ์ž˜ ๋ชป ๋œ๊ฒƒ ๊ฐ™์€๋ฐ์š”.. ์ข€๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด ์ €๋„ ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๊ฒ ๋„ค์š”.. ์ €๋„ hog ์•ˆํ•œ์ง€ ์˜ค๋ž˜๋˜์–ด์„œ ๊ธฐ์–ต์ด ๊ฐ€๋ฌผ๊ฐ€๋ฌผํ•˜๊ฑฐ๋“ ์š”.. ^^
      ์ง€๊ธˆ ์—…๋ฌด๋„ ๋งŽ๊ณ  ํ•ด์„œ.. ์ œ๊ฐ€ ๋นจ๋ฆฌ ๋‹ต๋ณ€ ๋ชป๋“œ๋ฆฌ๋Š” ์  ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

      Delete
  12. how can i train my HOG descriptor to detect partial parts of the human body

    ReplyDelete
  13. your meaning is, you want to create your own hog feature right?
    and training by svm.
    if that case, this post will help

    http://study.marearts.com/2016/01/svm-hog-learning-and-detection-methods.html

    Thanks for your interesting.

    ReplyDelete
  14. Hy Mister, I'm new in HOG Feature, I want to ask, when i used hog.compute in a loop like u do, it always crash and throwing an exception, it said "Invalid_parameter:
    _SCL_SECURE_INVALID_ARGUMENT_NO_ASSERT;"
    it only compute 1 image then always crashing in the next image and throw that exception (it can't looping). Please help me solve my problem here. Thanks

    ReplyDelete
    Replies
    1. Hi, The first loop succeeded, but does it fail from the second?
      Does the image size change?
      Thank you.

      Delete
  15. Thank you for your reply, I'm really sorry I can't reply faster, there are no change of the images except before calculating HOG, like u did above. This is my code, can you check it where I did wrong, Thank you for your response.

    int main(int argc, const char* argv[])
    {
    string folder = "D:\\Project\\TA\\Data_Trainer\\Clip_Images\\Positif Training1\\pisang\\"; // folder input
    string suffix = ".png";
    int counter = 0;
    Mat img, img_gray;
    Mat img1, img2;

    for (int i = 0; i < 10; i++) {
    stringstream ss;
    cout << "check point 0 " << endl;
    ss << setw(4) << setfill('0') << counter; // 0000, 0001, 0002, etc...
    //ss << counter; // 0000, 0001, 0002, etc...
    string number = ss.str();

    string name = folder + number + suffix;
    img = imread(name);
    if (img.empty()) cout << "No image Loaded" << endl;
    else cout << "image " << counter << " Loaded Successfully" << endl;
    cout << name << endl;

    //Parameter
    setWidth = 32, setHeight = 32;

    //resizing
    resize(img, img, Size(setWidth, setHeight)); //Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) );

    //GrayScaling
    cvtColor(img, img_gray, CV_RGB2GRAY); //gray

    //extract feature
    HOGDescriptor hog(Size(setWidth, setHeight), Size(8, 8), Size(4, 4), Size(4, 4), 9);
    // Size(32,16), //winSize
    // Size(8,8), //blocksize
    // Size(4,4), //blockStride,
    // Size(4,4), //cellSize,
    // 9, //nbins,
    vector< float> descriptorsValues;
    vector< Point> locations;

    hog.compute(img_gray, descriptorsValues, Size(0, 0), Size(0, 0), locations);
    // img, descriptor, winStride, Padding, Location

    if (descriptorsValues.empty()) cout << "descriptorValues empty" << endl;
    if (locations.empty()) cout << "location empty" << endl;

    v_descriptorsValues.push_back(descriptorsValues);
    v_locations.push_back(locations);

    printf("row =%d ", v_descriptorsValues.size());
    printf(" ,col =%d\n", v_descriptorsValues[0].size());

    //show image
    //imshow("origin", img);
    waitKey(3);

    cout << "loop: " << counter << endl;
    counter++;
    //img.release();
    //img_gray.release();
    cout << "check point 1" << endl;
    descriptorsValues.clear();
    locations.clear();

    }

    ReplyDelete
  16. Hopefully anyone can help me about this, I really need your help :)

    ReplyDelete