00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string>
00021 #include <math.h>
00022 #include "APImage.h"
00023
00024 #ifdef USE_VIGRA
00025 using namespace vigra;
00026 #endif
00027
00028 APImage::APImage(string p) {
00029 this->path=p;
00030 }
00031
00032 bool APImage::open() {
00033
00034 #ifdef USE_VIGRA
00035 try
00036 {
00037
00038
00039 ImageImportInfo info(this->path.c_str());
00040
00041
00042 if(info.isGrayscale())
00043 {
00044
00045 vigra::BImage in(info.width(), info.height());
00046 this->imgBW=new BImage(info.width(), info.height());
00047
00048 importImage(info, destImage(*this->imgBW));
00049 }
00050 else
00051 {
00052
00053 BRGBImage in(info.width(), info.height());
00054
00055
00056 this->imgBW=new BImage(info.width(), info.height());
00057
00058 importImage(info, destImage(in));
00059
00060
00061
00062 vigra::BRGBImage::Iterator sy = in.upperLeft();
00063
00064
00065
00066 vigra::BRGBImage::Iterator send = in.lowerRight();
00067
00068
00069
00070 vigra::BImage::Iterator dy = (*this->imgBW).upperLeft();
00071
00072
00073 for(; sy.y != send.y; ++sy.y, ++dy.y)
00074 {
00075
00076
00077 vigra::BRGBImage::Iterator sx = sy;
00078
00079
00080
00081 vigra::BImage::Iterator dx = dy;
00082
00083
00084 for(; sx.x != send.x; ++sx.x, ++dx.x)
00085 {
00086 RGBValue<int,0u,1u,2u> pixel = *sx;
00087
00088
00089 *dx = vigra::round(0.3*pixel.red() + 0.59*pixel.green() + 0.11*pixel.blue());
00090 }
00091 }
00092
00093 }
00094 return true;
00095 }
00096 catch (...)
00097 {
00098
00099 return false;
00100 }
00101 #endif
00102 }
00103 void APImage::convolute(int* kernel,int dim1, int dim2,double scale) {
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 }
00156 int APImage::getPixel(int x,int y) {
00157 #ifdef USE_VIGRA
00158 return (*this->imgBW)(x,y);
00159 #endif
00160 #ifdef USE_OPENCV
00161 CvScalar s=cvGet2D(imgBW,x,y);
00162 s.val[0];
00163 #endif
00164 }
00165 int APImage::getWidth() {
00166 return this->imgBW->width();
00167 }
00168 int APImage::getWidthBW() {
00169 return this->imgBW->width();
00170 }
00171 int APImage::getHeight() {
00172 return this->imgBW->height();
00173 }
00174 int APImage::getHeightBW() {
00175 return this->imgBW->height();
00176 }
00177 APImage* APImage::getCopy() {
00178 return new APImage("");
00179 }
00180 void APImage::scale(double factor) {
00181
00182
00183
00184
00185
00186 }
00187 void APImage::show() {
00188 #ifdef USE_VIGRA
00189 string add = "00det_";
00190 add.append(this->getPath());
00191
00192 cout << "Results:"<< add << endl;
00193 exportImage(srcImageRange(*this->imgBW), ImageExportInfo(add.c_str()));
00194 #endif
00195 #ifdef USE_OPENCV
00196 cvNamedWindow( "Image view", 1 );
00197 cvShowAPImage( "Image view", this->img);
00198 cvWaitKey(0);
00199 cvDestroyWindow( "Image view" );
00200 #endif
00201
00202 }
00203 void APImage::drawCircle(int x,int y, int radius) {
00204
00205 #ifdef USE_VIGRA
00206
00207 (*this->imgBW)(x,y) = 255;
00208 (*this->imgBW)(x+1,y+1) = 255;
00209 (*this->imgBW)(x-1,y-1) = 255;
00210 (*this->imgBW)(x-1,y+1) = 255;
00211 (*this->imgBW)(x+1,y-1) = 255;
00212
00213 #endif
00214
00215
00216 #ifdef USE_OPENCV
00217 cvCircle(this->img, cvPoint(x,y), radius, cvScalar(0,255,0), 1);
00218 cvCircle(this->img, cvPoint(x,y), 0, cvScalar(0,255,0), 1);
00219 #endif
00220
00221 }
00222 void APImage::drawRectangle(int x,int y, int radius) {
00223
00224 }
00225
00226 void APImage::drawLine(int x1,int y1, int x2,int y2) {
00227
00228 #ifdef USE_OPENCV
00229 cvLine(this->img,cvPoint(x1,y1),cvPoint(x2,y2),cvScalar(0,255,255));
00230 #endif
00231
00232 }
00233
00234 void APImage::smooth() {
00235
00236 }
00240 void APImage::integrate() {
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 this->integral.clear();
00253 this->integral.resize(this->getWidthBW());
00254 for(int i=0;i<this->getWidthBW();i++) {
00255 this->integral[i].resize(this->getHeightBW());
00256 for(int j=0; j<this->getHeightBW();j++) {
00257
00258 this->integral[i][j]=this->_getValue4Integral(i,j-1)+this->_getValue4Integral(i-1,j)+this->getPixel(i,j)-this->_getValue4Integral(i-1,j-1);
00259 }
00260
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 }
00272 int APImage::_getValue4Integral(int x, int y) {
00273 if(x==-1 || y==-1) return 0;
00274 else return this->integral[x][y];
00275 }
00276 int APImage::getIntegralPixel(int x,int y) {
00277 return this->integral[x][y];
00278 }
00279 int APImage::getRegionSum(int y1, int x1, int y2, int x2) {
00280 if(x1<=0) x1=1;
00281 if(y1<=0) y1=1;
00282 if(x2<=0) x2=1;
00283 if(y2<=0) y2=1;
00284 if(x1>=this->getWidthBW()) x1=this->getWidthBW()-1;
00285 if(x2>=this->getWidthBW()) x2=this->getWidthBW()-1;
00286 if(y1>=this->getHeightBW()) y1=this->getHeightBW()-1;
00287 if(y2>=this->getHeightBW()) y2=this->getHeightBW()-1;
00288 return this->integral[x2][y2]+this->integral[x1-1][y1-1]-this->integral[x1-1][y2]-this->integral[x2][y1-1];
00289 }
00290 string APImage::getPath() {
00291 return this->path;
00292 }
00293
00294
00295
00296
00297
00298
00299 template <class SrcIterator, class SrcAccessor, class BackInsertable>
00300 void APImage::_cannyEdgelList1(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00301 BackInsertable & edgels, double scale,vector<int>* point )
00302 {
00303 _cannyEdgelList(src.first, src.second, src.third, edgels, scale, point);
00304 }
00305
00306 template <class SrcIterator, class SrcAccessor, class BackInsertable>
00307 void APImage::_cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src,
00308 BackInsertable & edgels, double scale, vector<int>* point)
00309 {
00310 int w = lr.x - ul.x;
00311 int h = lr.y - ul.y;
00312
00313
00314 typedef typename
00315 NumericTraits<typename SrcAccessor::value_type>::RealPromote
00316 TmpType;
00317
00318 BasicImage<TmpType> tmp(w,h), dx(w,h), dy(w,h);
00319
00320 Kernel1D<double> smooth, grad;
00321
00322 smooth.initGaussian(scale);
00323 grad.initGaussianDerivative(scale, 1);
00324
00325 separableConvolveX(srcIterRange(ul, lr, src), destImage(tmp), kernel1d(grad));
00326 separableConvolveY(srcImageRange(tmp), destImage(dx), kernel1d(smooth));
00327
00328 separableConvolveY(srcIterRange(ul, lr, src), destImage(tmp), kernel1d(grad));
00329 separableConvolveX(srcImageRange(tmp), destImage(dy), kernel1d(smooth));
00330
00331 combineTwoImages(srcImageRange(dx), srcImage(dy), destImage(tmp),
00332 MagnitudeFunctor<TmpType>());
00333
00334
00335
00336 internalCannyFindEdgels(dx, dy, tmp, edgels, point);
00337 }
00338
00339 template <class Image1, class Image2, class BackInsertable>
00340 void APImage::_internalCannyFindEdgels(Image1 const & gx,
00341 Image1 const & gy,
00342 Image2 const & magnitude,
00343 BackInsertable & edgels, vector<int>* p)
00344 {
00345 typedef typename Image1::value_type PixelType;
00346 double t = 0.5 / VIGRA_CSTD::sin(M_PI/8.0);
00347
00348
00349
00350
00351
00352 vector<int > point= *p;
00353 PixelType gradx = gx(p[0],p[1]);
00354 PixelType grady = gy(p[0],p[1]);
00355
00356 double orientation = VIGRA_CSTD::atan2(-grady, gradx) - M_PI * 1.5;
00357 if(orientation < 0.0)
00358 orientation += 2.0*M_PI;
00359 Edgel edgel;
00360 edgel.orientation=orientation;
00361 edgels.push_back(edgel);
00362
00363
00364 for(int y=1; y<gx.height()-1; ++y)
00365 {
00366 for(int x=1; x<gx.width()-1; ++x)
00367 {
00368 gradx = gx(x,y);
00369 grady = gy(x,y);
00370 double mag = magnitude(x, y);
00371
00372 int dx = (int)VIGRA_CSTD::floor(gradx*t/mag + 0.5);
00373 int dy = (int)VIGRA_CSTD::floor(grady*t/mag + 0.5);
00374
00375 int x1 = x - dx,
00376 x2 = x + dx,
00377 y1 = y - dy,
00378 y2 = y + dy;
00379
00380 PixelType m1 = magnitude(x1, y1);
00381 PixelType m3 = magnitude(x2, y2);
00382
00383 if(m1 < mag && m3 <= mag)
00384 {
00385 Edgel edgel;
00386
00387
00388 PixelType del = (m1 - m3) / 2.0 / (m1 + m3 - 2.0*mag);
00389 edgel.x = x + dx*del;
00390 edgel.y = y + dy*del;
00391 edgel.strength = mag;
00392 orientation = VIGRA_CSTD::atan2(-grady, gradx) - M_PI * 1.5;
00393 if(orientation < 0.0)
00394 orientation += 2.0*M_PI;
00395 edgel.orientation = orientation;
00396 edgels.push_back(edgel);
00397 }
00398 }
00399 }
00400 }
00401
00402 void APImage::test() {
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 }