Path: blob/master/apps/traincascade/imagestorage.cpp
16337 views
#include "opencv2/core.hpp"1#include "opencv2/core/core_c.h"2#include "opencv2/imgproc.hpp"3#include "opencv2/imgcodecs.hpp"45#include "imagestorage.h"6#include <stdio.h>7#include <iostream>8#include <fstream>910using namespace std;11using namespace cv;1213bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize )14{15return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);16}1718CvCascadeImageReader::NegReader::NegReader()19{20src.create( 0, 0 , CV_8UC1 );21img.create( 0, 0, CV_8UC1 );22point = offset = Point( 0, 0 );23scale = 1.0F;24scaleFactor = 1.4142135623730950488016887242097F;25stepFactor = 0.5F;26}2728bool CvCascadeImageReader::NegReader::create( const string _filename, Size _winSize )29{30string str;31std::ifstream file(_filename.c_str());32if ( !file.is_open() )33return false;3435while( !file.eof() )36{37std::getline(file, str);38str.erase(str.find_last_not_of(" \n\r\t")+1);39if (str.empty()) break;40if (str.at(0) == '#' ) continue; /* comment */41imgFilenames.push_back(str);42}43file.close();4445winSize = _winSize;46last = round = 0;47return true;48}4950bool CvCascadeImageReader::NegReader::nextImg()51{52Point _offset = Point(0,0);53size_t count = imgFilenames.size();54for( size_t i = 0; i < count; i++ )55{56src = imread( imgFilenames[last++], 0 );57if( src.empty() ){58last %= count;59continue;60}61round += last / count;62round = round % (winSize.width * winSize.height);63last %= count;6465_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 );67if( !src.empty() && src.type() == CV_8UC168&& _offset.x >= 0 && _offset.y >= 0 )69break;70}7172if( src.empty() )73return false; // no appropriate image74point = offset = _offset;75scale = max( ((float)winSize.width + point.x) / ((float)src.cols),76((float)winSize.height + point.y) / ((float)src.rows) );7778Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );79resize( src, img, sz, 0, 0, INTER_LINEAR_EXACT );80return true;81}8283bool CvCascadeImageReader::NegReader::get( Mat& _img )84{85CV_Assert( !_img.empty() );86CV_Assert( _img.type() == CV_8UC1 );87CV_Assert( _img.cols == winSize.width );88CV_Assert( _img.rows == winSize.height );8990if( img.empty() )91if ( !nextImg() )92return false;9394Mat mat( winSize.height, winSize.width, CV_8UC1,95(void*)(img.ptr(point.y) + point.x * img.elemSize()), img.step );96mat.copyTo(_img);9798if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )99point.x += (int)(stepFactor * winSize.width);100else101{102point.x = offset.x;103if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )104point.y += (int)(stepFactor * winSize.height);105else106{107point.y = offset.y;108scale *= scaleFactor;109if( scale <= 1.0F )110resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ), 0, 0, INTER_LINEAR_EXACT );111else112{113if ( !nextImg() )114return false;115}116}117}118return true;119}120121CvCascadeImageReader::PosReader::PosReader()122{123file = 0;124vec = 0;125}126127bool CvCascadeImageReader::PosReader::create( const string _filename )128{129if ( file )130fclose( file );131file = fopen( _filename.c_str(), "rb" );132133if( !file )134return false;135short tmp = 0;136if( fread( &count, sizeof( count ), 1, file ) != 1 ||137fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||138fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||139fread( &tmp, sizeof( tmp ), 1, file ) != 1 )140CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) );141base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );142if( feof( file ) )143return false;144last = 0;145vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );146CV_Assert( vec );147return true;148}149150bool CvCascadeImageReader::PosReader::get( Mat &_img )151{152CV_Assert( _img.rows * _img.cols == vecSize );153uchar tmp = 0;154size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );155if( elements_read != 1 )156CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is "157"insufficient count of samples in given vec-file.\n");158elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );159if( elements_read != (size_t)(vecSize) )160CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");161162if( feof( file ) || last++ >= count )163CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n");164165for( int r = 0; r < _img.rows; r++ )166{167for( int c = 0; c < _img.cols; c++ )168_img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];169}170return true;171}172173void CvCascadeImageReader::PosReader::restart()174{175CV_Assert( file );176last = 0;177fseek( file, base, SEEK_SET );178}179180CvCascadeImageReader::PosReader::~PosReader()181{182if (file)183fclose( file );184cvFree( &vec );185}186187188