opencv/apps/traincascade/imagestorage.cpp
Andrey Kamaev 2a6fb2867e Remove all using directives for STL namespace and members
Made all STL usages explicit to be able automatically find all usages of
particular class or function.
2013-02-25 15:04:17 +04:00

190 lines
5.4 KiB
C++

#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "cv.h"
#include "imagestorage.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;
bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize )
{
return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);
}
CvCascadeImageReader::NegReader::NegReader()
{
src.create( 0, 0 , CV_8UC1 );
img.create( 0, 0, CV_8UC1 );
point = offset = Point( 0, 0 );
scale = 1.0F;
scaleFactor = 1.4142135623730950488016887242097F;
stepFactor = 0.5F;
}
bool CvCascadeImageReader::NegReader::create( const string _filename, Size _winSize )
{
string dirname, str;
std::ifstream file(_filename.c_str());
if ( !file.is_open() )
return false;
size_t pos = _filename.rfind('\\');
char dlmrt = '\\';
if (pos == string::npos)
{
pos = _filename.rfind('/');
dlmrt = '/';
}
dirname = pos == string::npos ? "" : _filename.substr(0, pos) + dlmrt;
while( !file.eof() )
{
std::getline(file, str);
if (str.empty()) break;
if (str.at(0) == '#' ) continue; /* comment */
imgFilenames.push_back(dirname + str);
}
file.close();
winSize = _winSize;
last = round = 0;
return true;
}
bool CvCascadeImageReader::NegReader::nextImg()
{
Point _offset = Point(0,0);
size_t count = imgFilenames.size();
for( size_t i = 0; i < count; i++ )
{
src = imread( imgFilenames[last++], 0 );
if( src.empty() )
continue;
round += last / count;
round = round % (winSize.width * winSize.height);
last %= count;
_offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
_offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
if( !src.empty() && src.type() == CV_8UC1
&& offset.x >= 0 && offset.y >= 0 )
break;
}
if( src.empty() )
return false; // no appropriate image
point = offset = _offset;
scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
((float)winSize.height + point.y) / ((float)src.rows) );
Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
resize( src, img, sz );
return true;
}
bool CvCascadeImageReader::NegReader::get( Mat& _img )
{
CV_Assert( !_img.empty() );
CV_Assert( _img.type() == CV_8UC1 );
CV_Assert( _img.cols == winSize.width );
CV_Assert( _img.rows == winSize.height );
if( img.empty() )
if ( !nextImg() )
return false;
Mat mat( winSize.height, winSize.width, CV_8UC1,
(void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step );
mat.copyTo(_img);
if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
point.x += (int)(stepFactor * winSize.width);
else
{
point.x = offset.x;
if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
point.y += (int)(stepFactor * winSize.height);
else
{
point.y = offset.y;
scale *= scaleFactor;
if( scale <= 1.0F )
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
else
{
if ( !nextImg() )
return false;
}
}
}
return true;
}
CvCascadeImageReader::PosReader::PosReader()
{
file = 0;
vec = 0;
}
bool CvCascadeImageReader::PosReader::create( const string _filename )
{
if ( file )
fclose( file );
file = fopen( _filename.c_str(), "rb" );
if( !file )
return false;
short tmp = 0;
if( fread( &count, sizeof( count ), 1, file ) != 1 ||
fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) );
base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
if( feof( file ) )
return false;
last = 0;
vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
CV_Assert( vec );
return true;
}
bool CvCascadeImageReader::PosReader::get( Mat &_img )
{
CV_Assert( _img.rows * _img.cols == vecSize );
uchar tmp = 0;
size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );
if( elements_read != 1 )
CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is "
"insufficient count of samples in given vec-file.\n");
elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );
if( elements_read != (size_t)(vecSize) )
CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");
if( feof( file ) || last++ >= count )
CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n");
for( int r = 0; r < _img.rows; r++ )
{
for( int c = 0; c < _img.cols; c++ )
_img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];
}
return true;
}
void CvCascadeImageReader::PosReader::restart()
{
CV_Assert( file );
last = 0;
fseek( file, base, SEEK_SET );
}
CvCascadeImageReader::PosReader::~PosReader()
{
if (file)
fclose( file );
cvFree( &vec );
}