imagestorage.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "opencv2/core.hpp"
  2. #include "opencv2/imgproc.hpp"
  3. #include "opencv2/imgcodecs.hpp"
  4. #include "imagestorage.h"
  5. #include <stdio.h>
  6. #include <iostream>
  7. #include <fstream>
  8. using namespace std;
  9. using namespace cv;
  10. bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize )
  11. {
  12. return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);
  13. }
  14. CvCascadeImageReader::NegReader::NegReader()
  15. {
  16. src.create( 0, 0 , CV_8UC1 );
  17. img.create( 0, 0, CV_8UC1 );
  18. point = offset = Point( 0, 0 );
  19. scale = 1.0F;
  20. scaleFactor = 1.4142135623730950488016887242097F;
  21. stepFactor = 0.5F;
  22. }
  23. bool CvCascadeImageReader::NegReader::create( const string _filename, Size _winSize )
  24. {
  25. string str;
  26. std::ifstream file(_filename.c_str());
  27. if ( !file.is_open() )
  28. return false;
  29. while( !file.eof() )
  30. {
  31. std::getline(file, str);
  32. str.erase(str.find_last_not_of(" \n\r\t")+1);
  33. if (str.empty()) break;
  34. if (str.at(0) == '#' ) continue; /* comment */
  35. imgFilenames.push_back(str);
  36. }
  37. file.close();
  38. winSize = _winSize;
  39. last = round = 0;
  40. return true;
  41. }
  42. bool CvCascadeImageReader::NegReader::nextImg()
  43. {
  44. Point _offset = Point(0,0);
  45. size_t count = imgFilenames.size();
  46. for( size_t i = 0; i < count; i++ )
  47. {
  48. src = imread( imgFilenames[last++], IMREAD_GRAYSCALE );
  49. if( src.empty() ){
  50. last %= count;
  51. continue;
  52. }
  53. round += last / count;
  54. round = round % (winSize.width * winSize.height);
  55. last %= count;
  56. _offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
  57. _offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
  58. if( !src.empty() && src.type() == CV_8UC1
  59. && _offset.x >= 0 && _offset.y >= 0 )
  60. break;
  61. }
  62. if( src.empty() )
  63. return false; // no appropriate image
  64. point = offset = _offset;
  65. scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
  66. ((float)winSize.height + point.y) / ((float)src.rows) );
  67. Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
  68. resize( src, img, sz, 0, 0, INTER_LINEAR_EXACT );
  69. return true;
  70. }
  71. bool CvCascadeImageReader::NegReader::get( Mat& _img )
  72. {
  73. CV_Assert( !_img.empty() );
  74. CV_Assert( _img.type() == CV_8UC1 );
  75. CV_Assert( _img.cols == winSize.width );
  76. CV_Assert( _img.rows == winSize.height );
  77. if( img.empty() )
  78. if ( !nextImg() )
  79. return false;
  80. Mat mat( winSize.height, winSize.width, CV_8UC1,
  81. (void*)(img.ptr(point.y) + point.x * img.elemSize()), img.step );
  82. mat.copyTo(_img);
  83. if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
  84. point.x += (int)(stepFactor * winSize.width);
  85. else
  86. {
  87. point.x = offset.x;
  88. if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
  89. point.y += (int)(stepFactor * winSize.height);
  90. else
  91. {
  92. point.y = offset.y;
  93. scale *= scaleFactor;
  94. if( scale <= 1.0F )
  95. resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ), 0, 0, INTER_LINEAR_EXACT );
  96. else
  97. {
  98. if ( !nextImg() )
  99. return false;
  100. }
  101. }
  102. }
  103. return true;
  104. }
  105. CvCascadeImageReader::PosReader::PosReader()
  106. {
  107. file = 0;
  108. vec = 0;
  109. }
  110. bool CvCascadeImageReader::PosReader::create( const string _filename )
  111. {
  112. if ( file )
  113. fclose( file );
  114. file = fopen( _filename.c_str(), "rb" );
  115. if( !file )
  116. return false;
  117. short tmp = 0;
  118. if( fread( &count, sizeof( count ), 1, file ) != 1 ||
  119. fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
  120. fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
  121. fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
  122. CV_Error_( cv::Error::StsParseError, ("wrong file format for %s\n", _filename.c_str()) );
  123. base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
  124. if( feof( file ) )
  125. return false;
  126. last = 0;
  127. vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
  128. CV_Assert( vec );
  129. return true;
  130. }
  131. bool CvCascadeImageReader::PosReader::get( Mat &_img )
  132. {
  133. CV_Assert( _img.rows * _img.cols == vecSize );
  134. uchar tmp = 0;
  135. size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );
  136. if( elements_read != 1 )
  137. CV_Error( cv::Error::StsBadArg, "Can not get new positive sample. The most possible reason is "
  138. "insufficient count of samples in given vec-file.\n");
  139. elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );
  140. if( elements_read != (size_t)(vecSize) )
  141. CV_Error( cv::Error::StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");
  142. if( feof( file ) || last++ >= count )
  143. CV_Error( cv::Error::StsBadArg, "Can not get new positive sample. vec-file is over.\n");
  144. for( int r = 0; r < _img.rows; r++ )
  145. {
  146. for( int c = 0; c < _img.cols; c++ )
  147. _img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];
  148. }
  149. return true;
  150. }
  151. void CvCascadeImageReader::PosReader::restart()
  152. {
  153. CV_Assert( file );
  154. last = 0;
  155. fseek( file, base, SEEK_SET );
  156. }
  157. CvCascadeImageReader::PosReader::~PosReader()
  158. {
  159. if (file)
  160. fclose( file );
  161. cvFree( &vec );
  162. }