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