25 #include "StatFactory.h"
28 filter2d::Filter2d::Filter2d(
void)
37 int filter2d::Filter2d::pushNoDataValue(
double noDataValue)
39 if(find(m_noDataValues.begin(),m_noDataValues.end(),noDataValue)==m_noDataValues.end())
40 m_noDataValues.push_back(noDataValue);
41 return(m_noDataValues.size());
51 smoothNoData(input, output,dim,dim);
56 smooth(input, output,dim,dim);
62 for(
int j=0;j<dimY;++j){
63 m_taps[j].resize(dimX);
64 for(
int i=0;i<dimX;++i)
67 filter(input,output,
false,
true,
true);
73 for(
int j=0;j<dimY;++j){
74 m_taps[j].resize(dimX);
75 for(
int i=0;i<dimX;++i)
78 filter(input,output,
false,
true,
false);
84 int dimX=m_taps[0].size();
85 int dimY=m_taps.size();
87 const char* pszMessage;
88 void* pProgressArg=NULL;
89 GDALProgressFunc pfnProgress=GDALTermProgress;
91 pfnProgress(progress,pszMessage,pProgressArg);
92 for(
int iband=0;iband<input.nrOfBand();++iband){
94 std::vector<double> outBuffer(input.nrOfCol());
98 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
100 input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
102 catch(std::string errorstring){
103 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
108 for(
int y=0;y<input.nrOfRow();++y){
112 inBuffer.erase(inBuffer.begin());
114 if(y+dimY/2<input.nrOfRow()){
117 inBuffer.push_back(inBuffer.back());
119 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
121 catch(std::string errorstring){
122 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
126 int over=y+dimY/2-input.nrOfRow();
127 int index=(inBuffer.size()-1)-over;
129 assert(index<inBuffer.size());
130 inBuffer.push_back(inBuffer[index]);
133 for(
int x=0;x<input.nrOfCol();++x){
138 for(
int imask=0;imask<m_noDataValues.size();++imask){
139 if(inBuffer[(dimY-1)/2][x]==m_noDataValues[imask]){
145 outBuffer[x]=inBuffer[(dimY-1)/2][x];
149 assert(!noData||masked);
150 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
151 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
157 else if(x>=input.nrOfCol()-(dimX-1)/2)
160 indexJ=(dimY-1)/2+abs(j);
161 else if(y>=input.nrOfRow()-(dimY-1)/2)
162 indexJ=(dimY-1)/2-abs(j);
165 for(
int imask=0;imask<m_noDataValues.size();++imask){
166 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
172 outBuffer[x]+=(m_taps[(dimY-1)/2+j][(dimX-1)/2+i]*inBuffer[indexJ][indexI]);
173 norm+=m_taps[(dimY-1)/2+j][(dimX-1)/2+i];
178 outBuffer[x]=(normalize&&norm)? abs(outBuffer[x])/norm : abs(outBuffer[x]);
179 else if(normalize&&norm!=0)
180 outBuffer[x]=outBuffer[x]/norm;
184 output.writeData(outBuffer,GDT_Float64,y,iband);
186 catch(std::string errorstring){
187 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
190 progress+=(output.nrOfRow()*iband);
191 progress/=output.nrOfBand()*output.nrOfRow();
192 pfnProgress(progress,pszMessage,pProgressArg);
198 void filter2d::Filter2d::majorVoting(
const std::string& inputFilename,
const std::string& outputFilename,
int dim,
const std::vector<int> &prior)
200 const char* pszMessage;
201 void* pProgressArg=NULL;
202 GDALProgressFunc pfnProgress=GDALTermProgress;
204 pfnProgress(progress,pszMessage,pProgressArg);
208 std::cout <<
"no prior information" << std::endl;
212 std::cout <<
"using priors ";
213 for(
int iclass=0;iclass<prior.size();++iclass)
214 std::cout <<
" " << static_cast<short>(prior[iclass]);
215 std::cout << std::endl;
220 input.open(inputFilename);
221 output.open(outputFilename,input);
229 dimX=m_taps[0].size();
237 std::vector<double> outBuffer(input.nrOfCol());
241 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
243 input.readData(inBuffer[indexJ],GDT_Float64,abs(j));
245 catch(std::string errorstring){
246 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
251 for(
int y=0;y<input.nrOfRow();++y){
255 inBuffer.erase(inBuffer.begin());
257 if(y+dimY/2<input.nrOfRow()){
260 inBuffer.push_back(inBuffer.back());
262 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2);
264 catch(std::string errorstring){
265 std::cerr << errorstring <<
"in line" << y << std::endl;
269 int over=y+dimY/2-input.nrOfRow();
270 int index=(inBuffer.size()-1)-over;
272 assert(index<inBuffer.size());
273 inBuffer.push_back(inBuffer[index]);
276 for(
int x=0;x<input.nrOfCol();++x){
278 std::map<int,int> occurrence;
279 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
280 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
281 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
286 else if(indexI>=input.nrOfCol())
287 indexI=input.nrOfCol()-i;
290 else if(y+j>=input.nrOfRow())
291 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
304 occurrence[inBuffer[indexJ][indexI]]+=prior[inBuffer[indexJ][indexI]-1];
307 ++occurrence[inBuffer[indexJ][indexI]];
310 std::map<int,int>::const_iterator maxit=occurrence.begin();
311 for(std::map<int,int>::const_iterator mit=occurrence.begin();mit!=occurrence.end();++mit){
312 if(mit->second>maxit->second)
315 if(occurrence[inBuffer[(dimY-1)/2][x]]<maxit->second)
316 outBuffer[x]=maxit->first;
318 outBuffer[x]=inBuffer[(dimY-1)/2][x];
322 output.writeData(outBuffer,GDT_Float64,y);
324 catch(std::string errorstring){
325 std::cerr << errorstring <<
"in line" << y << std::endl;
327 progress=(1.0+y)/output.nrOfRow();
328 pfnProgress(progress,pszMessage,pProgressArg);
334 void filter2d::Filter2d::median(
const std::string& inputFilename,
const std::string& outputFilename,
int dim,
bool disc)
338 input.open(inputFilename);
339 output.open(outputFilename,input);
340 doit(input,output,
"median",dim,disc);
343 void filter2d::Filter2d::var(
const std::string& inputFilename,
const std::string& outputFilename,
int dim,
bool disc)
347 input.open(inputFilename);
348 output.open(outputFilename,input);
349 doit(input,output,
"var",dim,disc);
352 void filter2d::Filter2d::doit(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dim,
short down,
bool disc)
354 doit(input,output,method,dim,dim,down,disc);
357 void filter2d::Filter2d::doit(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dimX,
int dimY,
short down,
bool disc)
359 const char* pszMessage;
360 void* pProgressArg=NULL;
361 GDALProgressFunc pfnProgress=GDALTermProgress;
363 pfnProgress(progress,pszMessage,pProgressArg);
369 for(
int iband=0;iband<input.nrOfBand();++iband){
371 std::vector<double> outBuffer((input.nrOfCol()+down-1)/down);
375 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
377 input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
379 catch(std::string errorstring){
380 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
384 for(
int y=0;y<input.nrOfRow();++y){
388 inBuffer.erase(inBuffer.begin());
390 if(y+dimY/2<input.nrOfRow()){
393 inBuffer.push_back(inBuffer.back());
395 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
397 catch(std::string errorstring){
398 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
402 int over=y+dimY/2-input.nrOfRow();
403 int index=(inBuffer.size()-1)-over;
405 assert(index<inBuffer.size());
406 inBuffer.push_back(inBuffer[index]);
409 if((y+1+down/2)%down)
411 for(
int x=0;x<input.nrOfCol();++x){
412 if((x+1+down/2)%down)
415 std::vector<double> windowBuffer;
416 std::map<long int,int> occurrence;
417 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
418 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
419 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
421 if(disc&&(d2>(dimX/2)*(dimY/2)))
427 else if(indexI>=input.nrOfCol())
428 indexI=input.nrOfCol()-i;
431 else if(y+j>=input.nrOfRow())
432 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
436 for(
int imask=0;imask<m_noDataValues.size();++imask){
437 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
443 std::vector<short>::const_iterator vit=m_class.begin();
445 ++occurrence[inBuffer[indexJ][indexI]];
447 while(vit!=m_class.end()){
448 if(inBuffer[indexJ][indexI]==*(vit++))
449 ++occurrence[inBuffer[indexJ][indexI]];
452 windowBuffer.push_back(inBuffer[indexJ][indexI]);
456 switch(getFilterType(method)){
457 case(filter2d::median):
458 if(windowBuffer.empty())
459 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
461 outBuffer[x/down]=stat.median(windowBuffer);
463 case(filter2d::var):{
464 if(windowBuffer.empty())
465 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
467 outBuffer[x/down]=stat.var(windowBuffer);
470 case(filter2d::stdev):{
471 if(windowBuffer.empty())
472 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
474 outBuffer[x/down]=sqrt(stat.var(windowBuffer));
477 case(filter2d::mean):{
478 if(windowBuffer.empty())
479 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
481 outBuffer[x/down]=stat.mean(windowBuffer);
484 case(filter2d::min):{
485 if(windowBuffer.empty())
486 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
488 outBuffer[x/down]=stat.mymin(windowBuffer);
491 case(filter2d::ismin):{
492 if(windowBuffer.empty())
493 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
495 outBuffer[x/down]=(stat.mymin(windowBuffer)==windowBuffer[centre])? 1:0;
498 case(filter2d::minmax):{
501 if(windowBuffer.empty())
502 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
504 stat.minmax(windowBuffer,windowBuffer.begin(),windowBuffer.end(),min,max);
508 outBuffer[x/down]=windowBuffer[centre];
512 case(filter2d::max):{
513 if(windowBuffer.empty())
514 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
516 outBuffer[x/down]=stat.mymax(windowBuffer);
519 case(filter2d::ismax):{
520 if(windowBuffer.empty())
521 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
523 outBuffer[x/down]=(stat.mymax(windowBuffer)==windowBuffer[centre])? 1:0;
526 case(filter2d::order):{
527 if(windowBuffer.empty())
528 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
531 double ubound=dimX*dimY;
532 double theMin=stat.mymin(windowBuffer);
533 double theMax=stat.mymax(windowBuffer);
534 double scale=(ubound-lbound)/(theMax-theMin);
535 outBuffer[x/down]=
static_cast<short>(scale*(windowBuffer[centre]-theMin)+lbound);
539 case(filter2d::sum):{
540 outBuffer[x/down]=stat.sum(windowBuffer);
543 case(filter2d::percentile):{
544 assert(m_threshold.size());
545 outBuffer[x/down]=stat.percentile(windowBuffer,windowBuffer.begin(),windowBuffer.end(),m_threshold[0]);
548 case(filter2d::homog):
549 if(occurrence.size()==1)
550 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
552 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
554 case(filter2d::heterog):{
555 if(occurrence.size()==windowBuffer.size())
556 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
558 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
578 case(filter2d::density):{
579 if(windowBuffer.size()){
580 std::vector<short>::const_iterator vit=m_class.begin();
581 while(vit!=m_class.end())
582 outBuffer[x/down]+=100.0*occurrence[*(vit++)]/windowBuffer.size();
585 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
588 case(filter2d::countid):{
589 if(windowBuffer.size())
590 outBuffer[x/down]=occurrence.size();
592 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
595 case(filter2d::mode):{
596 if(occurrence.size()){
597 std::map<long int,int>::const_iterator maxit=occurrence.begin();
598 for(std::map<long int,int>::const_iterator mit=occurrence.begin();mit!=occurrence.end();++mit){
599 if(mit->second>maxit->second)
602 if(occurrence[inBuffer[(dimY-1)/2][x]]<maxit->second)
603 outBuffer[x/down]=maxit->first;
605 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
608 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
611 case(filter2d::threshold):{
612 assert(m_class.size()==m_threshold.size());
613 if(windowBuffer.size()){
614 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
615 for(
int iclass=0;iclass<m_class.size();++iclass){
616 if(100.0*(occurrence[m_class[iclass]])/windowBuffer.size()>m_threshold[iclass])
617 outBuffer[x/down]=m_class[iclass];
621 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
624 case(filter2d::scramble):{
625 if(windowBuffer.size()){
626 int randomIndex=std::rand()%windowBuffer.size();
627 if(randomIndex>=windowBuffer.size())
628 outBuffer[x/down]=windowBuffer.back();
629 else if(randomIndex<0)
630 outBuffer[x/down]=windowBuffer[0];
632 outBuffer[x/down]=windowBuffer[randomIndex];
635 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
638 case(filter2d::mixed):{
639 enum Type { BF=11, CF=12, MF=13, NF=20, W=30 };
640 double nBF=occurrence[BF];
641 double nCF=occurrence[CF];
642 double nMF=occurrence[MF];
643 double nNF=occurrence[NF];
644 double nW=occurrence[W];
645 if(windowBuffer.size()){
646 if((nBF+nCF+nMF)&&(nBF+nCF+nMF>=nNF+nW)){
647 if(nBF/(nBF+nCF)>=0.75)
648 outBuffer[x/down]=BF;
649 else if(nCF/(nBF+nCF)>=0.75)
650 outBuffer[x/down]=CF;
652 outBuffer[x/down]=MF;
658 outBuffer[x/down]=NF;
662 outBuffer[x/down]=inBuffer[indexJ][indexI];
666 std::ostringstream ess;
667 ess <<
"Error: filter method " << method <<
" not supported" << std::endl;
673 progress=(1.0+y/down);
674 progress+=(output.nrOfRow()*iband);
675 progress/=output.nrOfBand()*output.nrOfRow();
676 pfnProgress(progress,pszMessage,pProgressArg);
679 output.writeData(outBuffer,GDT_Float64,y/down,iband);
681 catch(std::string errorstring){
682 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
686 pfnProgress(1.0,pszMessage,pProgressArg);
689 void filter2d::Filter2d::mrf(
const ImgReaderGdal& input,
ImgWriterGdal& output,
int dimX,
int dimY,
double beta,
bool eightConnectivity,
short down,
bool verbose){
690 assert(m_class.size()>1);
692 for(
int iclass1=0;iclass1<m_class.size();++iclass1)
693 for(
int iclass2=0;iclass2<m_class.size();++iclass2)
694 fullBeta[iclass1][iclass2]=beta;
695 mrf(input,output,dimX,dimY,fullBeta,eightConnectivity,down,verbose);
701 const char* pszMessage;
702 void* pProgressArg=NULL;
703 GDALProgressFunc pfnProgress=GDALTermProgress;
705 pfnProgress(progress,pszMessage,pProgressArg);
712 assert(input.nrOfBand()==1);
713 assert(output.nrOfBand()==m_class.size());
714 assert(m_class.size()>1);
715 assert(beta.size()==m_class.size());
719 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
721 input.readData(inBuffer[indexJ],GDT_Int16,abs(j));
723 catch(std::string errorstring){
724 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
728 for(
int y=0;y<input.nrOfRow();++y){
732 inBuffer.erase(inBuffer.begin());
734 if(y+dimY/2<input.nrOfRow()){
737 inBuffer.push_back(inBuffer.back());
739 input.readData(inBuffer[inBuffer.size()-1],GDT_Int16,y+dimY/2);
741 catch(std::string errorstring){
742 std::cerr << errorstring <<
"in line " << y << std::endl;
746 int over=y+dimY/2-input.nrOfRow();
747 int index=(inBuffer.size()-1)-over;
749 assert(index<inBuffer.size());
750 inBuffer.push_back(inBuffer[index]);
753 if((y+1+down/2)%down)
755 for(
int x=0;x<input.nrOfCol();++x){
756 if((x+1+down/2)%down)
758 std::vector<short> potential(m_class.size());
759 for(
int iclass=0;iclass<m_class.size();++iclass){
761 outBuffer[iclass][x/down]=0;
763 std::vector<double> windowBuffer;
764 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
765 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
766 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
767 if(i!=0&&j!=0&&!eightConnectivity)
775 else if(indexI>=input.nrOfCol())
776 indexI=input.nrOfCol()-i;
779 else if(y+j>=input.nrOfRow())
780 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
784 for(
int imask=0;imask<m_noDataValues.size();++imask){
785 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
791 for(
int iclass=0;iclass<m_class.size();++iclass){
792 if(inBuffer[indexJ][indexI]==m_class[iclass])
793 potential[iclass]+=1;
799 for(
int iclass1=0;iclass1<m_class.size();++iclass1){
800 assert(beta[iclass1].size()==m_class.size());
802 for(
int iclass2=0;iclass2<m_class.size();++iclass2)
804 pot+=potential[iclass2]*beta[iclass1][iclass2];
805 double prior=exp(-pot);
806 outBuffer[iclass1][x/down]=prior;
810 for(
int iclass1=0;iclass1<m_class.size();++iclass1)
811 outBuffer[iclass1][x/down]/=norm;
814 progress=(1.0+y/down)/output.nrOfRow();
815 pfnProgress(progress,pszMessage,pProgressArg);
817 assert(outBuffer.size()==m_class.size());
818 assert(y<output.nrOfRow());
819 for(
int iclass=0;iclass<m_class.size();++iclass){
820 assert(outBuffer[iclass].size()==output.nrOfCol());
822 output.writeData(outBuffer[iclass],GDT_Float64,y/down,iclass);
824 catch(std::string errorstring){
825 std::cerr << errorstring <<
"in class " << iclass <<
", line " << y << std::endl;
831 void filter2d::Filter2d::shift(
const ImgReaderGdal& input,
ImgWriterGdal& output,
double offsetX,
double offsetY,
double randomSigma, RESAMPLE resample,
bool verbose)
833 assert(input.nrOfCol()==output.nrOfCol());
834 assert(input.nrOfRow()==output.nrOfRow());
835 assert(input.nrOfBand()==output.nrOfBand());
836 const char* pszMessage;
837 void* pProgressArg=NULL;
838 GDALProgressFunc pfnProgress=GDALTermProgress;
840 pfnProgress(progress,pszMessage,pProgressArg);
844 for(
int iband=0;iband<input.nrOfBand();++iband){
845 input.readDataBlock(inBuffer,GDT_Float64,0,inBuffer.nCols()-1,0,inBuffer.nRows()-1,iband);
846 shift(inBuffer,outBuffer,offsetX,offsetY,randomSigma,resample,verbose);
847 output.writeDataBlock(outBuffer,GDT_Float64,0,outBuffer.nCols()-1,0,outBuffer.nRows()-1,iband);
958 void filter2d::Filter2d::morphology(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dimX,
int dimY,
const std::vector<double> &angle,
bool disc)
960 const char* pszMessage;
961 void* pProgressArg=NULL;
962 GDALProgressFunc pfnProgress=GDALTermProgress;
964 pfnProgress(progress,pszMessage,pProgressArg);
970 for(
int iband=0;iband<input.nrOfBand();++iband){
972 std::vector<double> outBuffer(input.nrOfCol());
976 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
978 input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
981 catch(std::string errorstring){
982 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
985 for(
int y=0;y<input.nrOfRow();++y){
989 inBuffer.erase(inBuffer.begin());
991 if(y+dimY/2<input.nrOfRow()){
994 inBuffer.push_back(inBuffer.back());
996 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
998 catch(std::string errorstring){
999 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
1003 int over=y+dimY/2-input.nrOfRow();
1004 int index=(inBuffer.size()-1)-over;
1006 assert(index<inBuffer.size());
1007 inBuffer.push_back(inBuffer[index]);
1010 for(
int x=0;x<input.nrOfCol();++x){
1011 double currentValue=inBuffer[(dimY-1)/2][x];
1012 outBuffer[x]=currentValue;
1013 std::vector<double> statBuffer;
1014 bool currentMasked=
false;
1015 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
1016 for(
int imask=0;imask<m_noDataValues.size();++imask){
1017 if(currentValue==m_noDataValues[imask]){
1023 outBuffer[x]=currentValue;
1026 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
1027 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
1029 if(disc&&(d2>(dimX/2)*(dimY/2)))
1036 theta=atan(static_cast<double>(-j)/(static_cast<double>(i)));
1038 theta=-atan(static_cast<double>(j)/(static_cast<double>(i)));
1042 theta=PI-atan(static_cast<double>(-j)/(static_cast<double>(-i)));
1044 theta=PI+atan(static_cast<double>(j)/(static_cast<double>(-i)));
1051 theta=360-(theta/PI*180)+90;
1056 bool alligned=
false;
1057 for(
int iangle=0;iangle<angle.size();++iangle){
1058 if(sqrt((theta-angle[iangle])*(theta-angle[iangle]))<10){
1070 else if(indexI>=input.nrOfCol())
1071 indexI=input.nrOfCol()-i;
1074 else if(y+j>=input.nrOfRow())
1075 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
1077 indexJ=(dimY-1)/2+j;
1082 for(
int imask=0;imask<m_noDataValues.size();++imask){
1083 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
1090 for(
int iclass=0;iclass<m_class.size();++iclass){
1091 if(inBuffer[indexJ][indexI]==m_class[iclass]){
1097 statBuffer.push_back(binValue);
1099 statBuffer.push_back(inBuffer[indexJ][indexI]);
1103 if(statBuffer.size()){
1104 switch(getFilterType(method)){
1105 case(filter2d::dilate):
1106 outBuffer[x]=stat.mymax(statBuffer);
1108 case(filter2d::erode):
1109 outBuffer[x]=stat.mymin(statBuffer);
1112 std::ostringstream ess;
1113 ess <<
"Error: morphology method " << method <<
" not supported, choose " << filter2d::dilate <<
" (dilate) or " << filter2d::erode <<
" (erode)" << std::endl;
1118 if(outBuffer[x]&&m_class.size())
1119 outBuffer[x]=m_class[0];
1124 output.writeData(outBuffer,GDT_Float64,y,iband);
1126 catch(std::string errorstring){
1127 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
1130 progress+=(output.nrOfRow()*iband);
1131 progress/=output.nrOfBand()*output.nrOfRow();
1132 pfnProgress(progress,pszMessage,pProgressArg);
1137 void filter2d::Filter2d::shadowDsm(
const ImgReaderGdal& input,
ImgWriterGdal& output,
double sza,
double saa,
double pixelSize,
short shadowFlag){
1140 input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, 0);
1141 shadowDsm(inputBuffer, outputBuffer, sza, saa, pixelSize, shadowFlag);
1142 output.writeDataBlock(outputBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,0);
1145 void filter2d::Filter2d::dwtForward(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
1147 for(
int iband=0;iband<input.nrOfBand();++iband){
1148 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1149 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1150 dwtForward(theBuffer, wavelet_type, family);
1151 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1155 void filter2d::Filter2d::dwtInverse(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
1157 for(
int iband=0;iband<input.nrOfBand();++iband){
1158 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1159 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1160 dwtInverse(theBuffer, wavelet_type, family);
1161 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1165 void filter2d::Filter2d::dwtCut(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family,
double cut,
bool verbose){
1167 for(
int iband=0;iband<input.nrOfBand();++iband){
1168 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1169 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1170 dwtCut(theBuffer, wavelet_type, family, cut);
1171 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1175 void filter2d::Filter2d::linearFeature(
const ImgReaderGdal& input,
ImgWriterGdal& output,
float angle,
float angleStep,
float maxDistance,
float eps,
bool l1,
bool a1,
bool l2,
bool a2,
int band,
bool verbose){
1177 std::vector< Vector2d<float> > outputBuffer;
1178 input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, band);
1180 maxDistance=sqrt(static_cast<float>(input.nrOfCol()*input.nrOfRow()));
1181 linearFeature(inputBuffer,outputBuffer,angle,angleStep,maxDistance,eps, l1, a1, l2, a2,verbose);
1182 for(
int iband=0;iband<outputBuffer.size();++iband)
1183 output.writeDataBlock(outputBuffer[iband],GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1186 void filter2d::Filter2d::linearFeature(
const Vector2d<float>& input, std::vector<
Vector2d<float> >& output,
float angle,
float angleStep,
float maxDistance,
float eps,
bool l1,
bool a1,
bool l2,
bool a2,
bool verbose)
1198 output.resize(nband);
1199 for(
int iband=0;iband<output.size();++iband)
1200 output[iband].resize(input.nRows(),input.nCols());
1202 maxDistance=sqrt(static_cast<float>(input.nRows()*input.nCols()));
1205 const char* pszMessage;
1206 void* pProgressArg=NULL;
1207 GDALProgressFunc pfnProgress=GDALTermProgress;
1209 pfnProgress(progress,pszMessage,pProgressArg);
1210 for(
int y=0;y<input.nRows();++y){
1211 for(
int x=0;x<input.nCols();++x){
1212 float currentValue=input[y][x];
1215 float lineDistance1=0;
1216 float lineDistance2=maxDistance;
1220 for(northAngle=0;northAngle<180;northAngle+=angleStep){
1221 if(angle<=360&&angle>=0&&angle!=northAngle)
1225 std::cout <<
"northAngle: " << northAngle << std::endl;
1226 float currentDistance=0;
1228 for(
short side=0;side<=1;side+=1){
1229 theDir=PI/2.0-DEG2RAD(northAngle)+side*PI;
1232 std::cout <<
"theDir in deg: " << RAD2DEG(theDir) << std::endl;
1237 std::cout <<
"theDir in deg: " << RAD2DEG(theDir) << std::endl;
1238 float nextValue=currentValue;
1239 for(
float currentRay=1;currentRay<maxDistance;++currentRay){
1240 indexI=x+currentRay*cos(theDir);
1241 indexJ=y-currentRay*sin(theDir);
1242 if(indexJ<0||indexJ>=input.size())
1244 if(indexI<0||indexI>=input[indexJ].size())
1246 nextValue=input[indexJ][indexI];
1248 std::cout <<
"x: " << x << std::endl;
1249 std::cout <<
"y: " << y << std::endl;
1250 std::cout <<
"currentValue: " << currentValue << std::endl;
1251 std::cout <<
"theDir in degrees: " << RAD2DEG(theDir) << std::endl;
1252 std::cout <<
"cos(theDir): " << cos(theDir) << std::endl;
1253 std::cout <<
"sin(theDir): " << sin(theDir) << std::endl;
1254 std::cout <<
"currentRay: " << currentRay << std::endl;
1255 std::cout <<
"currentDistance: " << currentDistance << std::endl;
1256 std::cout <<
"indexI: " << indexI << std::endl;
1257 std::cout <<
"indexJ: " << indexJ << std::endl;
1258 std::cout <<
"nextValue: " << nextValue << std::endl;
1260 if(fabs(currentValue-nextValue)<=eps){
1264 std::cout <<
"currentDistance: " << currentDistance <<
", continue" << std::endl;
1268 std::cout <<
"currentDistance: " << currentDistance <<
", break" << std::endl;
1273 if(lineDistance1<currentDistance){
1274 lineDistance1=currentDistance;
1275 lineAngle1=northAngle;
1277 if(lineDistance2>currentDistance){
1278 lineDistance2=currentDistance;
1279 lineAngle2=northAngle;
1282 std::cout <<
"lineDistance1: " << lineDistance1 << std::endl;
1283 std::cout <<
"lineAngle1: " << lineAngle1 << std::endl;
1284 std::cout <<
"lineDistance2: " << lineDistance2 << std::endl;
1285 std::cout <<
"lineAngle2: " << lineAngle2 << std::endl;
1290 output[iband++][y][x]=lineDistance1;
1292 output[iband++][y][x]=lineAngle1;
1294 output[iband++][y][x]=lineDistance2;
1296 output[iband++][y][x]=lineAngle2;
1297 assert(iband==nband);
1300 progress/=input.nRows();
1301 pfnProgress(progress,pszMessage,pProgressArg);