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 
create(const string _posFilename,const string _negFilename,Size _winSize)14 bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize )
15 {
16     return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);
17 }
18 
NegReader()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 
create(const string _filename,Size _winSize)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 
nextImg()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 
get(Mat & _img)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 
PosReader()121 CvCascadeImageReader::PosReader::PosReader()
122 {
123     file = 0;
124     vec = 0;
125 }
126 
create(const string _filename)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 
get(Mat & _img)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 
restart()173 void CvCascadeImageReader::PosReader::restart()
174 {
175     CV_Assert( file );
176     last = 0;
177     fseek( file, base, SEEK_SET );
178 }
179 
~PosReader()180 CvCascadeImageReader::PosReader::~PosReader()
181 {
182     if (file)
183         fclose( file );
184     cvFree( &vec );
185 }
186