Home | History | Annotate | Download | only in traincascade
      1 #include "opencv2/core.hpp"
      2 #include "opencv2/core/core_c.h"
      3 #include "opencv2/imgproc.hpp"
      4 #include "opencv2/imgcodecs.hpp"
      5 
      6 #include "imagestorage.h"
      7 #include <stdio.h>
      8 #include <iostream>
      9 #include <fstream>
     10 
     11 using namespace std;
     12 using namespace cv;
     13 
     14 bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize )
     15 {
     16     return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);
     17 }
     18 
     19 CvCascadeImageReader::NegReader::NegReader()
     20 {
     21     src.create( 0, 0 , CV_8UC1 );
     22     img.create( 0, 0, CV_8UC1 );
     23     point = offset = Point( 0, 0 );
     24     scale       = 1.0F;
     25     scaleFactor = 1.4142135623730950488016887242097F;
     26     stepFactor  = 0.5F;
     27 }
     28 
     29 bool CvCascadeImageReader::NegReader::create( const string _filename, Size _winSize )
     30 {
     31     string dirname, str;
     32     std::ifstream file(_filename.c_str());
     33     if ( !file.is_open() )
     34         return false;
     35 
     36     while( !file.eof() )
     37     {
     38         std::getline(file, str);
     39         if (str.empty()) break;
     40         if (str.at(0) == '#' ) continue; /* comment */
     41         imgFilenames.push_back(str);
     42     }
     43     file.close();
     44 
     45     winSize = _winSize;
     46     last = round = 0;
     47     return true;
     48 }
     49 
     50 bool CvCascadeImageReader::NegReader::nextImg()
     51 {
     52     Point _offset = Point(0,0);
     53     size_t count = imgFilenames.size();
     54     for( size_t i = 0; i < count; i++ )
     55     {
     56         src = imread( imgFilenames[last++], 0 );
     57         if( src.empty() ){
     58             last %= count;
     59             continue;
     60         }
     61         round += last / count;
     62         round = round % (winSize.width * winSize.height);
     63         last %= count;
     64 
     65         _offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
     66         _offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
     67         if( !src.empty() && src.type() == CV_8UC1
     68                 && _offset.x >= 0 && _offset.y >= 0 )
     69             break;
     70     }
     71 
     72     if( src.empty() )
     73         return false; // no appropriate image
     74     point = offset = _offset;
     75     scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
     76                  ((float)winSize.height + point.y) / ((float)src.rows) );
     77 
     78     Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
     79     resize( src, img, sz );
     80     return true;
     81 }
     82 
     83 bool CvCascadeImageReader::NegReader::get( Mat& _img )
     84 {
     85     CV_Assert( !_img.empty() );
     86     CV_Assert( _img.type() == CV_8UC1 );
     87     CV_Assert( _img.cols == winSize.width );
     88     CV_Assert( _img.rows == winSize.height );
     89 
     90     if( img.empty() )
     91         if ( !nextImg() )
     92             return false;
     93 
     94     Mat mat( winSize.height, winSize.width, CV_8UC1,
     95         (void*)(img.ptr(point.y) + point.x * img.elemSize()), img.step );
     96     mat.copyTo(_img);
     97 
     98     if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
     99         point.x += (int)(stepFactor * winSize.width);
    100     else
    101     {
    102         point.x = offset.x;
    103         if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
    104             point.y += (int)(stepFactor * winSize.height);
    105         else
    106         {
    107             point.y = offset.y;
    108             scale *= scaleFactor;
    109             if( scale <= 1.0F )
    110                 resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
    111             else
    112             {
    113                 if ( !nextImg() )
    114                     return false;
    115             }
    116         }
    117     }
    118     return true;
    119 }
    120 
    121 CvCascadeImageReader::PosReader::PosReader()
    122 {
    123     file = 0;
    124     vec = 0;
    125 }
    126 
    127 bool CvCascadeImageReader::PosReader::create( const string _filename )
    128 {
    129     if ( file )
    130         fclose( file );
    131     file = fopen( _filename.c_str(), "rb" );
    132 
    133     if( !file )
    134         return false;
    135     short tmp = 0;
    136     if( fread( &count, sizeof( count ), 1, file ) != 1 ||
    137         fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
    138         fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
    139         fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
    140         CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) );
    141     base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
    142     if( feof( file ) )
    143         return false;
    144     last = 0;
    145     vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
    146     CV_Assert( vec );
    147     return true;
    148 }
    149 
    150 bool CvCascadeImageReader::PosReader::get( Mat &_img )
    151 {
    152     CV_Assert( _img.rows * _img.cols == vecSize );
    153     uchar tmp = 0;
    154     size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );
    155     if( elements_read != 1 )
    156         CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is "
    157                                 "insufficient count of samples in given vec-file.\n");
    158     elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );
    159     if( elements_read != (size_t)(vecSize) )
    160         CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");
    161 
    162     if( feof( file ) || last++ >= count )
    163         CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n");
    164 
    165     for( int r = 0; r < _img.rows; r++ )
    166     {
    167         for( int c = 0; c < _img.cols; c++ )
    168             _img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];
    169     }
    170     return true;
    171 }
    172 
    173 void CvCascadeImageReader::PosReader::restart()
    174 {
    175     CV_Assert( file );
    176     last = 0;
    177     fseek( file, base, SEEK_SET );
    178 }
    179 
    180 CvCascadeImageReader::PosReader::~PosReader()
    181 {
    182     if (file)
    183         fclose( file );
    184     cvFree( &vec );
    185 }
    186