Can create training set in PNG format

The format of the training set can be changed with the `-pngoutput` key.
Output image will be resized to a 640x480 size if greater.
pull/3156/head
Grigory Serebryakov 11 years ago
parent 41040e589f
commit 81aefed13a
  1. 3
      apps/haartraining/CMakeLists.txt
  2. 44
      apps/haartraining/createsamples.cpp
  3. 177
      apps/haartraining/cvhaartraining.cpp
  4. 63
      apps/haartraining/cvhaartraining.h
  5. 255
      apps/haartraining/cvsamplesoutput.cpp
  6. 49
      apps/haartraining/cvsamplesoutput.h
  7. 34
      apps/haartraining/ioutput.h
  8. 84
      doc/user_guide/ug_traincascade.rst

@ -29,6 +29,9 @@ set(cvhaartraining_lib_src
cvhaarclassifier.cpp
cvhaartraining.cpp
cvsamples.cpp
cvsamplesoutput.cpp
cvsamplesoutput.h
ioutput.h
)
add_library(opencv_haartraining_engine STATIC ${cvhaartraining_lib_src})

@ -54,6 +54,7 @@
using namespace std;
#include "cvhaartraining.h"
#include "ioutput.h"
int main( int argc, char* argv[] )
{
@ -76,6 +77,7 @@ int main( int argc, char* argv[] )
double scale = 4.0;
int width = 24;
int height = 24;
bool pngoutput = false; /* whether to make the samples in png or in jpg*/
srand((unsigned int)time(0));
@ -92,7 +94,8 @@ int main( int argc, char* argv[] )
" [-maxyangle <max_y_rotation_angle = %f>]\n"
" [-maxzangle <max_z_rotation_angle = %f>]\n"
" [-show [<scale = %f>]]\n"
" [-w <sample_width = %d>]\n [-h <sample_height = %d>]\n",
" [-w <sample_width = %d>]\n [-h <sample_height = %d>]\n"
" [-pngoutput]",
argv[0], num, bgcolor, bgthreshold, maxintensitydev,
maxxangle, maxyangle, maxzangle, scale, width, height );
@ -172,6 +175,10 @@ int main( int argc, char* argv[] )
{
height = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-pngoutput" ) )
{
pngoutput = true;
}
}
printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );
@ -190,10 +197,14 @@ int main( int argc, char* argv[] )
printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );
if( showsamples )
{
printf( "Scale: %g\n", scale );
printf( "Scale applied to display : %g\n", scale );
}
if( !pngoutput)
{
printf( "Original image whill be scaled to:\n");
printf( "\tWidth: $backgroundWidth / %d\n", width );
printf( "\tHeight: $backgroundHeight / %d\n", height );
}
printf( "Width: %d\n", width );
printf( "Height: %d\n", height );
/* determine action */
if( imagename && vecname )
@ -207,13 +218,30 @@ int main( int argc, char* argv[] )
printf( "Done\n" );
}
else if( imagename && bgfilename && infoname && pngoutput)
{
printf( "Create training set from a single image and a collection of backgrounds.\n"
"Output format: %s\n"
"Annotations are in a separate directory\n",
(( pngoutput ) ? "JPG" : "PNG") );
PngTrainingSetGenerator creator( infoname );
creator.create( imagename, bgcolor, bgthreshold, bgfilename, num,
invert, maxintensitydev, maxxangle, maxyangle, maxzangle,
showsamples, width, height );
printf( "Done\n" );
}
else if( imagename && bgfilename && infoname )
{
printf( "Create test samples from single image applying distortions...\n" );
printf( "Create test samples from single image applying distortions...\n"
"Output format: %s\n",
(( pngoutput ) ? "JPG" : "PNG") );
cvCreateTestSamples( infoname, imagename, bgcolor, bgthreshold, bgfilename, num,
invert, maxintensitydev,
maxxangle, maxyangle, maxzangle, showsamples, width, height );
TestSamplesGenerator creator( infoname );
creator.create( imagename, bgcolor, bgthreshold, bgfilename, num,
invert, maxintensitydev, maxxangle, maxyangle, maxzangle,
showsamples, width, height );
printf( "Done\n" );
}

@ -48,6 +48,8 @@
#include "cvhaartraining.h"
#include "_cvhaartraining.h"
#include "ioutput.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
@ -2841,8 +2843,6 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
cvReleaseMat( &features_idx );
}
void cvCreateTrainingSamples( const char* filename,
const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
@ -2942,45 +2942,43 @@ void cvCreateTrainingSamples( const char* filename,
}
#define CV_INFO_FILENAME "info.dat"
SamplesGenerator::SamplesGenerator( IOutput* _writer )
:writer(_writer)
{
}
void SamplesGenerator::showSamples(bool* show, CvMat *img) const
{
if( *show )
{
cvShowImage( "Image", img);
if( cvWaitKey( 0 ) == 27 )
{
*show = false;
}
}
}
void cvCreateTestSamples( const char* infoname,
const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
int showsamples,
int winwidth, int winheight )
void SamplesGenerator::create(const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
bool showsamples,
int winwidth, int winheight )
{
CvSampleDistortionData data;
assert( infoname != NULL );
assert( imgfilename != NULL );
assert( bgfilename != NULL );
if( !icvMkDir( infoname ) )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to create directory hierarchy: %s\n", infoname );
#endif /* CV_VERBOSE */
return;
}
if( icvStartSampleDistortion( imgfilename, bgcolor, bgthreshold, &data ) )
{
char fullname[PATH_MAX];
char* filename;
CvMat win;
FILE* info;
if( icvInitBackgroundReaders( bgfilename, cvSize( 10, 10 ) ) )
{
int i;
int x, y, width, height;
float scale;
float maxscale;
int inverse;
if( showsamples )
@ -2988,73 +2986,112 @@ void cvCreateTestSamples( const char* infoname,
cvNamedWindow( "Image", CV_WINDOW_AUTOSIZE );
}
info = fopen( infoname, "w" );
strcpy( fullname, infoname );
filename = strrchr( fullname, '\\' );
if( filename == NULL )
{
filename = strrchr( fullname, '/' );
}
if( filename == NULL )
{
filename = fullname;
}
else
{
filename++;
}
count = MIN( count, cvbgdata->count );
inverse = invert;
for( i = 0; i < count; i++ )
{
icvGetNextFromBackgroundData( cvbgdata, cvbgreader );
maxscale = MIN( 0.7F * cvbgreader->src.cols / winwidth,
0.7F * cvbgreader->src.rows / winheight );
if( maxscale < 1.0F ) continue;
CvRect boundingBox = getObjectPosition( cvSize( cvbgreader->src.cols,
cvbgreader->src.rows ),
cvGetSize(data.img),
cvSize( winwidth, winheight ) );
if(boundingBox.width <= 0 || boundingBox.height <= 0)
{
continue;
}
scale = (maxscale - 1.0F) * rand() / RAND_MAX + 1.0F;
width = (int) (scale * winwidth);
height = (int) (scale * winheight);
x = (int) ((0.1+0.8 * rand()/RAND_MAX) * (cvbgreader->src.cols - width));
y = (int) ((0.1+0.8 * rand()/RAND_MAX) * (cvbgreader->src.rows - height));
cvGetSubArr( &cvbgreader->src, &win, boundingBox );
cvGetSubArr( &cvbgreader->src, &win, cvRect( x, y ,width, height ) );
if( invert == CV_RANDOM_INVERT )
{
inverse = (rand() > (RAND_MAX/2));
}
icvPlaceDistortedSample( &win, inverse, maxintensitydev,
maxxangle, maxyangle, maxzangle,
1, 0.0, 0.0, &data );
writer->write( cvbgreader->src, boundingBox );
sprintf( filename, "%04d_%04d_%04d_%04d_%04d.jpg",
(i + 1), x, y, width, height );
if( info )
{
fprintf( info, "%s %d %d %d %d %d\n",
filename, 1, x, y, width, height );
}
cvSaveImage( fullname, &cvbgreader->src );
if( showsamples )
{
cvShowImage( "Image", &cvbgreader->src );
if( cvWaitKey( 0 ) == 27 )
{
showsamples = 0;
}
}
showSamples(&showsamples, &cvbgreader->src);
}
if( info ) fclose( info );
icvDestroyBackgroundReaders();
}
icvEndSampleDistortion( &data );
}
}
SamplesGenerator::~SamplesGenerator()
{
delete writer;
}
TestSamplesGenerator::TestSamplesGenerator(const char* filename)
:SamplesGenerator(IOutput::createOutput(filename,IOutput::JPG_TEST_SET))
{
}
CvSize TestSamplesGenerator::scaleObjectSize(const CvSize& bgImgSize,
const CvSize& ,
const CvSize& sampleSize) const
{
float scale;
float maxscale;
maxscale = MIN( 0.7F * bgImgSize.width / sampleSize.width,
0.7F * bgImgSize.height / sampleSize.height );
if( maxscale < 1.0F )
{
scale = -1.f;
}
else
{
scale = (maxscale - 1.0F) * rand() / RAND_MAX + 1.0F;
}
int width = (int) (scale * sampleSize.width);
int height = (int) (scale * sampleSize.height);
return cvSize( width, height );
}
CvRect SamplesGenerator::getObjectPosition(const CvSize& bgImgSize,
const CvSize& imgSize,
const CvSize& sampleSize) const
{
CvSize size = scaleObjectSize( bgImgSize, imgSize, sampleSize );
int width = size.width;
int height = size.height;
int x = (int) ((0.1 + 0.8 * rand() / RAND_MAX) * (bgImgSize.width - width));
int y = (int) ((0.1 + 0.8 * rand() / RAND_MAX) * (bgImgSize.height - height));
return cvRect( x, y, width, height );
}
PngTrainingSetGenerator::PngTrainingSetGenerator(const char* filename)
:SamplesGenerator(IOutput::createOutput(filename,IOutput::PNG_TRAINING_SET))
{
}
CvSize PngTrainingSetGenerator::scaleObjectSize( const CvSize& bgImgSize,
const CvSize& imgSize,
const CvSize& ) const
{
float scale;
scale = MIN( 0.3F * bgImgSize.width / imgSize.width,
0.3F * bgImgSize.height / imgSize.height );
int width = (int) (scale * imgSize.width);
int height = (int) (scale * imgSize.height);
return cvSize( width, height );
}
/* End of file. */

@ -48,6 +48,11 @@
#ifndef _CVHAARTRAINING_H_
#define _CVHAARTRAINING_H_
class IOutput;
struct CvRect;
struct CvSize;
struct CvMat;
/*
* cvCreateTrainingSamples
*
@ -84,13 +89,20 @@ void cvCreateTrainingSamples( const char* filename,
int showsamples = 0,
int winwidth = 24, int winheight = 24 );
void cvCreateTestSamples( const char* infoname,
const char* imgfilename, int bgcolor, int bgthreshold,
void cvCreatePngTrainingSet(const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
int winwidth, int winheight,
IOutput *writer );
void cvCreateTestSamples(const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
int showsamples,
int winwidth, int winheight );
int winwidth, int winheight,
IOutput* writer);
/*
* cvCreateTrainingSamplesFromInfo
@ -189,4 +201,49 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
int boosttype, int stumperror,
int maxtreesplits, int minpos, bool bg_vecfile = false );
class SamplesGenerator
{
public:
SamplesGenerator( IOutput* _writer );
void create( const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
bool showsamples,
int winwidth, int winheight);
virtual ~SamplesGenerator();
private:
virtual void showSamples( bool* showSamples, CvMat* img ) const;
CvRect getObjectPosition( const CvSize& bgImgSize,
const CvSize& imgSize,
const CvSize& sampleSize ) const;
virtual CvSize scaleObjectSize(const CvSize& bgImgSize,
const CvSize& imgSize ,
const CvSize& sampleSize) const =0 ;
private:
IOutput* writer;
};
class TestSamplesGenerator: public SamplesGenerator
{
public:
TestSamplesGenerator(const char* filename);
private:
CvSize scaleObjectSize(const CvSize& bgImgSize,
const CvSize& ,
const CvSize& sampleSize) const;
};
class PngTrainingSetGenerator: public SamplesGenerator
{
public:
PngTrainingSetGenerator(const char *filename);
private:
CvSize scaleObjectSize(const CvSize& bgImgSize,
const CvSize& imgSize ,
const CvSize& ) const;
};
#endif /* _CVHAARTRAINING_H_ */

@ -0,0 +1,255 @@
#include "cvsamplesoutput.h"
#include <cstdio>
#include "_cvcommon.h"
#include "opencv2/opencv.hpp"
/* print statistic info */
#define CV_VERBOSE 1
IOutput::IOutput()
: currentIdx(0)
{}
void IOutput::findFilePathPart(char **partOfPath, char *fullPath)
{
*partOfPath = strrchr( fullPath, '\\' );
if( *partOfPath == NULL )
{
*partOfPath = strrchr( fullPath, '/' );
}
if( *partOfPath == NULL )
{
*partOfPath = fullPath;
}
else
{
*partOfPath += 1;
}
}
IOutput* IOutput::createOutput(const char *filename,
IOutput::OutputType type)
{
IOutput* output = 0;
switch (type) {
case IOutput::PNG_TRAINING_SET:
output = new PngTrainingSetOutput();
break;
case IOutput::JPG_TEST_SET:
output = new TestSamplesOutput();
break;
default:
#if CV_VERBOSE
fprintf( stderr, "Invalid output type, valid types are: PNG_TRAINING_SET, JPG_TEST_SET");
#endif /* CV_VERBOSE */
return 0;
}
if ( output->init( filename ) )
return output;
else
return 0;
}
bool PngTrainingSetOutput::init( const char* annotationsListFileName )
{
IOutput::init( annotationsListFileName );
if(imgFileName == imgFullPath)
{
#if CV_VERBOSE
fprintf( stderr, "Invalid path to annotations file: %s\n"
"It should contain a parent directory name\n", imgFullPath );
#endif /* CV_VERBOSE */
return false;
}
const char* annotationsdirname = "/annotations/";
const char* positivesdirname = "/pos/";
imgFileName[-1] = '\0'; //erase slash at the end of the path
imgFileName -= 1;
//copy path to dataset top-level dir
strcpy(annotationFullPath, imgFullPath);
//find the name of annotation starting from the top-level dataset dir
findFilePathPart(&annotationRelativePath, annotationFullPath);
if( !strcmp( annotationRelativePath, ".." ) || !strcmp( annotationRelativePath, "." ) )
{
#if CV_VERBOSE
fprintf( stderr, "Invalid path to annotations file: %s\n"
"It should contain a parent directory name\n", annotationsListFileName );
#endif /* CV_VERBOSE */
return false;
}
//find the name of output image starting from the top-level dataset dir
findFilePathPart(&imgRelativePath, imgFullPath);
annotationFileName = annotationFullPath + strlen(annotationFullPath);
sprintf(annotationFileName, "%s", annotationsdirname);
annotationFileName += strlen(annotationFileName);
sprintf(imgFileName, "%s", positivesdirname);
imgFileName += strlen(imgFileName);
if( !icvMkDir( annotationFullPath ) )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to create directory hierarchy: %s\n", annotationFullPath );
#endif /* CV_VERBOSE */
return false;
}
if( !icvMkDir( imgFullPath ) )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to create directory hierarchy: %s\n", imgFullPath );
#endif /* CV_VERBOSE */
return false;
}
return true;
}
bool PngTrainingSetOutput::write( const CvMat& img,
const CvRect& boundingBox )
{
CvRect bbox = scaleBoundingBox(cvGetSize(&img), boundingBox);
sprintf( imgFileName,
"%04d_%04d_%04d_%04d_%04d",
++currentIdx,
bbox.x,
bbox.y,
bbox.width,
bbox.height );
sprintf( annotationFileName, "%s.txt", imgFileName );
fprintf( annotationsList, "%s\n", annotationRelativePath );
FILE* annotationFile = fopen( annotationFullPath, "w" );
if(annotationFile == 0)
{
return false;
}
sprintf( imgFileName + strlen(imgFileName), ".%s", extension );
fprintf( annotationFile,
"Image filename : \"%s\"\n"
"Bounding box for object 1 \"PASperson\" (Xmin, Ymin) - (Xmax, Ymax) : (%d, %d) - (%d, %d)",
imgRelativePath,
bbox.x,
bbox.y,
bbox.x + bbox.width,
bbox.y + bbox.height );
fclose( annotationFile );
writeImage(img);
return true;
}
void PngTrainingSetOutput::writeImage(const CvMat &img) const
{
CvSize origsize = cvGetSize(&img);
if( origsize.height > destImgHeight || origsize.width > destImgWidth )
{
CvMat result = cvMat( destImgHeight, destImgWidth, CV_8UC1,
cvAlloc( sizeof( uchar ) * destImgHeight * destImgWidth ) );
cvResize(&img, &result);
cvSaveImage( imgFullPath, &result );
cvFree( &(result.data.ptr) );
}
else
{
cvSaveImage( imgFullPath, &img);
}
return;
}
CvRect PngTrainingSetOutput::scaleBoundingBox(const CvSize& imgSize, const CvRect& bbox)
{
double scale = MAX( (float) destImgWidth / imgSize.width,
(float) destImgHeight / imgSize.height );
CvRect boundingBox = bbox;
int border = 5;
if( scale < 1. )
{
boundingBox.x = bbox.x * scale;
boundingBox.y = bbox.y * scale;
boundingBox.width = bbox.width * scale;
boundingBox.height = bbox.height * scale;
}
boundingBox.x -= border;
boundingBox.y -= border;
boundingBox.width += 2*border;
boundingBox.height += 2*border;
return boundingBox;
}
IOutput::~IOutput()
{
if(annotationsList)
{
fclose(annotationsList);
}
}
bool IOutput::init(const char *filename)
{
assert( filename != NULL );
if( !icvMkDir( filename ) )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to create directory hierarchy: %s\n", filename );
#endif /* CV_VERBOSE */
return false;
}
annotationsList = fopen( filename, "w" );
if( annotationsList == NULL )
{
#if CV_VERBOSE
fprintf( stderr, "Unable to create info file: %s\n", filename );
#endif /* CV_VERBOSE */
return false;
}
strcpy( imgFullPath, filename );
findFilePathPart( &imgFileName, imgFullPath );
return true;
}
bool TestSamplesOutput::write( const CvMat& img,
const CvRect& boundingBox )
{
sprintf( imgFileName, "%04d_%04d_%04d_%04d_%04d.jpg",
++currentIdx,
boundingBox.x,
boundingBox.y,
boundingBox.width,
boundingBox.height );
fprintf( annotationsList, "%s %d %d %d %d %d\n",
imgFullPath,
1,
boundingBox.x,
boundingBox.y,
boundingBox.width,
boundingBox.height );
cvSaveImage( imgFullPath, &img);
return true;
}

@ -0,0 +1,49 @@
#ifndef CVSAMPLESOUTPUT_H
#define CVSAMPLESOUTPUT_H
#include "ioutput.h"
class PngTrainingSetOutput: public IOutput
{
friend IOutput* IOutput::createOutput(const char *filename, OutputType type);
public:
virtual bool write( const CvMat& img,
const CvRect& boundingBox);
virtual ~PngTrainingSetOutput(){}
private:
PngTrainingSetOutput()
: extension("png")
, destImgWidth(640)
, destImgHeight(480)
{}
virtual bool init(const char* annotationsListFileName );
void writeImage( const CvMat& img ) const;
CvRect scaleBoundingBox(const CvSize& imgSize,
const CvRect& bbox);
private:
char annotationFullPath[PATH_MAX];
char* annotationFileName;
char* annotationRelativePath;
char* imgRelativePath;
const char* extension;
int destImgWidth;
int destImgHeight ;
};
class TestSamplesOutput: public IOutput
{
friend IOutput* IOutput::createOutput(const char *filename, OutputType type);
public:
virtual bool write( const CvMat& img,
const CvRect& boundingBox );
virtual ~TestSamplesOutput(){}
private:
TestSamplesOutput(){}
};
#endif // CVSAMPLESOUTPUT_H

@ -0,0 +1,34 @@
#ifndef IOUTPUT_H
#define IOUTPUT_H
#include <cstdio>
#include "_cvcommon.h"
struct CvMat;
struct CvRect;
class IOutput
{
public:
enum OutputType {PNG_TRAINING_SET, JPG_TEST_SET};
public:
virtual bool write( const CvMat& img,
const CvRect& boundingBox ) =0;
virtual ~IOutput();
static IOutput* createOutput( const char *filename, OutputType type );
protected:
IOutput();
/* finds the beginning of the last token in the path */
void findFilePathPart( char **partOfPath, char *fullPath );
virtual bool init( const char* filename );
protected:
int currentIdx;
char imgFullPath[PATH_MAX];
char* imgFileName;
FILE* annotationsList;
};
#endif // IOUTPUT_H

@ -117,9 +117,27 @@ Command line arguments:
Height (in pixels) of the output samples.
For following procedure is used to create a sample object instance:
* ``-pngoutput``
With this option switched on ``opencv_createsamples`` tool generates a collection of PNG samples and a number of associated annotation files, instead of a single ``vec`` file.
The ``opencv_createsamples`` utility may work in a number of modes, namely:
* Creating training set from a single image and a collection of backgrounds with a single ``vec`` file as an output;
* Converting the marked-up collection of samples into a ``vec`` format;
* Creating training set from a single image, as specified above, but with a collection of PNG images and associated annotation files as a result;
* Creating test set that consists of JPG samples collection and a signle file with annotations;
* Showing the content of the ``vec`` file.
Creating training set from a single image and a collection of backgrounds with a single ``vec`` file as an output
-----------------------------------------------------------------------------------------------------------------
The following procedure is used to create a sample object instance:
The source image is rotated randomly around all three axes. The chosen angle is limited my ``-max?angle``. Then pixels having the intensity from [``bg_color-bg_color_threshold``; ``bg_color+bg_color_threshold``] range are interpreted as transparent. White noise is added to the intensities of the foreground. If the ``-inv`` key is specified then foreground pixel intensities are inverted. If ``-randinv`` key is specified then algorithm randomly selects whether inversion should be applied to this sample. Finally, the obtained image is placed onto an arbitrary background from the background description file, resized to the desired size specified by ``-w`` and ``-h`` and stored to the vec-file, specified by the ``-vec`` command line option.
Converting the marked-up collection of samples into a ``vec`` format
--------------------------------------------------------------------
Positive samples also may be obtained from a collection of previously marked up images. This collection is described by a text file similar to background description file. Each line of this file corresponds to an image. The first element of the line is the filename. It is followed by the number of object instances. The following numbers are the coordinates of objects bounding rectangles (x, y, width, height).
An example of description file:
@ -150,6 +168,70 @@ In order to create positive samples from such collection, ``-info`` argument sho
The scheme of samples creation in this case is as follows. The object instances are taken from images. Then they are resized to target samples size and stored in output vec-file. No distortion is applied, so the only affecting arguments are ``-w``, ``-h``, ``-show`` and ``-num``.
Creating training set from a single image, but with a collection of PNG images and associated annotation files as a result
--------------------------------------------------------------------------------------------------------------------------
To obtain such behaviour the ``-img``, ``-bg`` and ``-info`` keys should be specified. The file name specified with ``-info`` key should include at least one level of directory hierarchy, that directory
will be used as the top-level dir for the training set.
For example, with the ``opencv_createsamples`` called as following:
opencv_createsamples -img /home/user/logo.png -bg /home/user/bg.txt -info /home/user/annotations.lst -pngoutput -maxxangle 0.1 -maxyangle 0.1 -maxzangle 0.1
The output will have the following structure:
.. code-block:: text
/home/user/
annotations/
0001_0107_0099_0195_0139.txt
0002_0107_0115_0195_0139.txt
...
neg/
<background files here>
pos/
0001_0107_0099_0195_0139.png
0002_0107_0115_0195_0139.png
...
annotations.lst
With ``*.txt`` files in ``annotations`` directory containing information about object bounding box on the sample in a next format:
.. code-block:: text
Image filename : "createsamples/pos/0002_0107_0115_0195_0139.png"
Bounding box for object 1 "PASperson" (Xmin, Ymin) - (Xmax, Ymax) : (107, 115) - (302, 254)
And ``annotations.lst`` file containing the list of all annotations file:
.. code-block:: text
createsamples/annotations/0001_0109_0209_0195_0139.txt
createsamples/annotations/0002_0241_0245_0139_0100.txt
Creating test set that consists of JPG samples collection and a signle file with annotations
--------------------------------------------------------------------------------------------
This variant of ``opencv_createsamples`` usage is very similar to the previous one, but generates the output in a different format;
Directory structure:
.. code-block:: text
info.dat
img1.jpg
img2.jpg
File info.dat:
.. code-block:: text
img1.jpg 1 140 100 45 45
img2.jpg 2 100 200 50 50 50 30 25 25
Showing the content of the ``vec`` file
---------------------------------------
``opencv_createsamples`` utility may be used for examining samples stored in positive samples file. In order to do this only ``-vec``, ``-w`` and ``-h`` parameters should be specified.
Note that for training, it does not matter how vec-files with positive samples are generated. But ``opencv_createsamples`` utility is the only one way to collect/create a vector file of positive samples, provided by OpenCV.

Loading…
Cancel
Save