哈尔训练中的对象标记

Object Marking in Haar training

本文关键字:对象 哈尔训      更新时间:2023-10-16

我正在做一个使用haar训练的OpenCV对象检测项目。我必须在图像中标记出物体存在的所有地方。所以,我需要一个代码打开每个图像,这样我就可以标记区域。与这里的类似:

#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
// for filelisting
#include <stdio.h>
#include <sys/io.h>
// for fileoutput
#include <string>
#include <fstream>
#include <sstream>
#include <dirent.h>
#include <sys/types.h>
using namespace std;
IplImage* image=0;
IplImage* image2=0;
//int start_roi=0;
int roi_x0=0;
int roi_y0=0;
int roi_x1=0;
int roi_y1=0;
int numOfRec=0;
int startDraw = 0;
char* window_name="<SPACE>add <B>save and load next <ESC>exit";
string IntToString(int num)
{
    ostringstream myStream; //creates an ostringstream object
    myStream << num << flush;
    /*
    * outputs the number into the string stream and then flushes
    * the buffer (makes sure the output is put into the stream)
    */
    return(myStream.str()); //returns the string form of the stringstream object
};
void on_mouse(int event,int x,int y,int flag, void *param)
{
    if(event==CV_EVENT_LBUTTONDOWN)
    {
        if(!startDraw)
        {
            roi_x0=x;
            roi_y0=y;
            startDraw = 1;
        } else {
            roi_x1=x;
            roi_y1=y;
            startDraw = 0;
        }
    }
    if(event==CV_EVENT_MOUSEMOVE && startDraw)
    {
        //redraw ROI selection
        image2=cvCloneImage(image);
        cvRectangle(image2,cvPoint(roi_x0,roi_y0),cvPoint(x,y),CV_RGB(255,0,255),1);
        cvShowImage(window_name,image2);
        cvReleaseImage(&image2);
    }
}
int main(int argc, char** argv)
{
    char iKey=0;
    string strPrefix;
    string strPostfix;
    string input_directory;
    string output_file;
    if(argc != 3) {
        fprintf(stderr, "%s output_info.txt raw/data/directory/n", argv[0]);
        return -1;
    } 
    input_directory = argv[2];
    output_file = argv[1];
    /* Get a file listing of all files with in the input directory */
    DIR    *dir_p = opendir (input_directory.c_str());
    struct dirent *dir_entry_p;
    if(dir_p == NULL) {
        fprintf(stderr, "Failed to open directory %sn", input_directory.c_str());
        return -1;
    }
    fprintf(stderr, "Object Marker: Input Directory: %s  Output File: %sn", input_directory.c_str(), output_file.c_str());
    //    init highgui
    cvAddSearchPath(input_directory);
    cvNamedWindow(window_name,1);
    cvSetMouseCallback(window_name,on_mouse, NULL);
    fprintf(stderr, "Opening directory...");
    //    init output of rectangles to the info file
    ofstream output(output_file.c_str());
    fprintf(stderr, "done.n");
    while((dir_entry_p = readdir(dir_p)) != NULL)
    {
        numOfRec=0;
        if(strcmp(dir_entry_p->d_name, ""))
        fprintf(stderr, "Examining file %sn", dir_entry_p->d_name);
        /* TODO: Assign postfix/prefix info */
        strPostfix="";
        //strPrefix=input_directory;
        strPrefix=dir_entry_p->d_name;
        //strPrefix+=bmp_file.name;
        fprintf(stderr, "Loading image %sn", strPrefix.c_str());
        if((image=cvLoadImage(strPrefix.c_str(),1)) != 0)
        {
            //    work on current image
            do
    {
                cvShowImage(window_name,image);
                // used cvWaitKey returns:
                //    <B>=66        save added rectangles and show next image
                //    <ESC>=27        exit program
                //    <Space>=32        add rectangle to current image
                //  any other key clears rectangle drawing only
                iKey=cvWaitKey(0);
                switch(iKey)
                {
                case 27:
                        cvReleaseImage(&image);
                        cvDestroyWindow(window_name);
                        return 0;
                case 32:
                        numOfRec++;
                printf("   %d. rect x=%dty=%dtx2h=%dty2=%dn",numOfRec,roi_x0,roi_y0,roi_x1,roi_y1);
                //printf("   %d. rect x=%dty=%dtwidth=%dtheight=%dn",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
                        // currently two draw directions possible:
                        //        from top left to bottom right or vice versa
                        if(roi_x0<roi_x1 && roi_y0<roi_y1)
                        {
                            printf("   %d. rect x=%dty=%dtwidth=%dtheight=%dn",numOfRec,roi_x0,roi_y0,roi_x1-roi_x0,roi_y1-roi_y0);
                            // append rectangle coord to previous line content
                            strPostfix+=" "+IntToString(roi_x0)+" "+IntToString(roi_y0)+" "+IntToString(roi_x1-roi_x0)+" "+IntToString(roi_y1-roi_y0);
                        }
                        else
                                                    //(roi_x0>roi_x1 && roi_y0>roi_y1)
                        {
                            printf(" hello line no 154n");
                            printf("   %d. rect x=%dty=%dtwidth=%dtheight=%dn",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
                            // append rectangle coord to previous line content
                            strPostfix+=" "+IntToString(roi_x1)+" "+IntToString(roi_y1)+" "+IntToString(roi_x0-roi_x1)+" "+IntToString      (roi_y0-roi_y1);
        }
                        break;
                }
            }
            while(iKey!=66);
            {
            // save to info file as later used for HaarTraining:
            //    <rel_path>bmp_file.name numOfRec x0 y0 width0 height0 x1 y1 width1 height1...
            if(numOfRec>0 && iKey==66)
            {
                //append line
                /* TODO: Store output information. */
                output << strPrefix << " "<< numOfRec << strPostfix <<"n";
            cvReleaseImage(&image);
            }
         else 
        {
            fprintf(stderr, "Failed to load image, %sn", strPrefix.c_str());
        }
    }
    }}
    output.close();
    cvDestroyWindow(window_name);
    closedir(dir_p);
    return 0;
}

我使用Visual Studio 10运行上述代码。当我运行上述代码时,它是打开加载所有图像的命令窗口(一个新的命名窗口也被打开,但得到,但它不是为我选择区域)然后关闭。

当我在VS10中使用启动而不调试选项运行它时,我可以看到:

Examining file img (6).jpeg
Loading image img (6).jpeg
Examining file img (6).JPG
Loading image img (6).JPG
Examining file img (7).jpeg
Loading image img (7).jpeg
Examining file img (7).jpg
Loading image img (7).jpg
Examining file img (8).jpeg
Loading image img (8).jpeg
Examining file img (8).jpg
Loading image img (8).jpg
Examining file img (9).jpeg
Loading image img (9).jpeg
Examining file img (9).jpg
Loading image img (9).jpg
Examining file img 1.jpeg
Loading image img 1.jpeg

对象标记失败,无法加载图像

我认为它跳过了:

if((image=cvLoadImage(strPrefix.c_str(),1)) != 0){.....}

部分代码

目前可用的Haar training对象标记工具很少。我在这个链接中使用这个工具。这对我来说非常有效。如果您想构建自己的工具,请遵循本教程。无论如何,我认为当涉及到Haar training时,开发工具来获取坐标是浪费时间,因为目前有可用的工具来获取坐标,这不是Haar training的主要目标。因为Haar training需要更多的时间来训练和创建级联XML文件。所以最好还是专注于训练。