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