Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/apps/traincascade/imagestorage.cpp
16337 views
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 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
str.erase(str.find_last_not_of(" \n\r\t")+1);
40
if (str.empty()) break;
41
if (str.at(0) == '#' ) continue; /* comment */
42
imgFilenames.push_back(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
last %= count;
60
continue;
61
}
62
round += last / count;
63
round = round % (winSize.width * winSize.height);
64
last %= count;
65
66
_offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
67
_offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
68
if( !src.empty() && src.type() == CV_8UC1
69
&& _offset.x >= 0 && _offset.y >= 0 )
70
break;
71
}
72
73
if( src.empty() )
74
return false; // no appropriate image
75
point = offset = _offset;
76
scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
77
((float)winSize.height + point.y) / ((float)src.rows) );
78
79
Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
80
resize( src, img, sz, 0, 0, INTER_LINEAR_EXACT );
81
return true;
82
}
83
84
bool CvCascadeImageReader::NegReader::get( Mat& _img )
85
{
86
CV_Assert( !_img.empty() );
87
CV_Assert( _img.type() == CV_8UC1 );
88
CV_Assert( _img.cols == winSize.width );
89
CV_Assert( _img.rows == winSize.height );
90
91
if( img.empty() )
92
if ( !nextImg() )
93
return false;
94
95
Mat mat( winSize.height, winSize.width, CV_8UC1,
96
(void*)(img.ptr(point.y) + point.x * img.elemSize()), img.step );
97
mat.copyTo(_img);
98
99
if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
100
point.x += (int)(stepFactor * winSize.width);
101
else
102
{
103
point.x = offset.x;
104
if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
105
point.y += (int)(stepFactor * winSize.height);
106
else
107
{
108
point.y = offset.y;
109
scale *= scaleFactor;
110
if( scale <= 1.0F )
111
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ), 0, 0, INTER_LINEAR_EXACT );
112
else
113
{
114
if ( !nextImg() )
115
return false;
116
}
117
}
118
}
119
return true;
120
}
121
122
CvCascadeImageReader::PosReader::PosReader()
123
{
124
file = 0;
125
vec = 0;
126
}
127
128
bool CvCascadeImageReader::PosReader::create( const string _filename )
129
{
130
if ( file )
131
fclose( file );
132
file = fopen( _filename.c_str(), "rb" );
133
134
if( !file )
135
return false;
136
short tmp = 0;
137
if( fread( &count, sizeof( count ), 1, file ) != 1 ||
138
fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
139
fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
140
fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
141
CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) );
142
base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
143
if( feof( file ) )
144
return false;
145
last = 0;
146
vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
147
CV_Assert( vec );
148
return true;
149
}
150
151
bool CvCascadeImageReader::PosReader::get( Mat &_img )
152
{
153
CV_Assert( _img.rows * _img.cols == vecSize );
154
uchar tmp = 0;
155
size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );
156
if( elements_read != 1 )
157
CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is "
158
"insufficient count of samples in given vec-file.\n");
159
elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );
160
if( elements_read != (size_t)(vecSize) )
161
CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");
162
163
if( feof( file ) || last++ >= count )
164
CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n");
165
166
for( int r = 0; r < _img.rows; r++ )
167
{
168
for( int c = 0; c < _img.cols; c++ )
169
_img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];
170
}
171
return true;
172
}
173
174
void CvCascadeImageReader::PosReader::restart()
175
{
176
CV_Assert( file );
177
last = 0;
178
fseek( file, base, SEEK_SET );
179
}
180
181
CvCascadeImageReader::PosReader::~PosReader()
182
{
183
if (file)
184
fclose( file );
185
cvFree( &vec );
186
}
187
188