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::proportion):{
549 if(windowBuffer.size()){
550 double sum=stat.sum(windowBuffer);
552 outBuffer[x/down]=100.0*windowBuffer[centre]/stat.sum(windowBuffer);
554 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
557 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
560 case(filter2d::homog):
561 if(occurrence.size()==1)
562 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
564 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
566 case(filter2d::heterog):{
567 if(occurrence.size()==windowBuffer.size())
568 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
570 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
590 case(filter2d::density):{
591 if(windowBuffer.size()){
592 std::vector<short>::const_iterator vit=m_class.begin();
593 while(vit!=m_class.end())
594 outBuffer[x/down]+=100.0*occurrence[*(vit++)]/windowBuffer.size();
597 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
600 case(filter2d::countid):{
601 if(windowBuffer.size())
602 outBuffer[x/down]=occurrence.size();
604 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
607 case(filter2d::mode):{
608 if(occurrence.size()){
609 std::map<long int,int>::const_iterator maxit=occurrence.begin();
610 for(std::map<long int,int>::const_iterator mit=occurrence.begin();mit!=occurrence.end();++mit){
611 if(mit->second>maxit->second)
614 if(occurrence[inBuffer[(dimY-1)/2][x]]<maxit->second)
615 outBuffer[x/down]=maxit->first;
617 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
620 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
623 case(filter2d::threshold):{
624 assert(m_class.size()==m_threshold.size());
625 if(windowBuffer.size()){
626 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
627 for(
int iclass=0;iclass<m_class.size();++iclass){
628 if(100.0*(occurrence[m_class[iclass]])/windowBuffer.size()>m_threshold[iclass])
629 outBuffer[x/down]=m_class[iclass];
633 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
636 case(filter2d::scramble):{
637 if(windowBuffer.size()){
638 int randomIndex=std::rand()%windowBuffer.size();
639 if(randomIndex>=windowBuffer.size())
640 outBuffer[x/down]=windowBuffer.back();
641 else if(randomIndex<0)
642 outBuffer[x/down]=windowBuffer[0];
644 outBuffer[x/down]=windowBuffer[randomIndex];
647 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
650 case(filter2d::mixed):{
651 enum Type { BF=11, CF=12, MF=13, NF=20, W=30 };
652 double nBF=occurrence[BF];
653 double nCF=occurrence[CF];
654 double nMF=occurrence[MF];
655 double nNF=occurrence[NF];
656 double nW=occurrence[W];
657 if(windowBuffer.size()){
658 if((nBF+nCF+nMF)&&(nBF+nCF+nMF>=nNF+nW)){
659 if(nBF/(nBF+nCF)>=0.75)
660 outBuffer[x/down]=BF;
661 else if(nCF/(nBF+nCF)>=0.75)
662 outBuffer[x/down]=CF;
664 outBuffer[x/down]=MF;
670 outBuffer[x/down]=NF;
674 outBuffer[x/down]=inBuffer[indexJ][indexI];
678 std::ostringstream ess;
679 ess <<
"Error: filter method " << method <<
" not supported" << std::endl;
685 progress=(1.0+y/down);
686 progress+=(output.nrOfRow()*iband);
687 progress/=output.nrOfBand()*output.nrOfRow();
688 pfnProgress(progress,pszMessage,pProgressArg);
691 output.writeData(outBuffer,GDT_Float64,y/down,iband);
693 catch(std::string errorstring){
694 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
698 pfnProgress(1.0,pszMessage,pProgressArg);
701 void filter2d::Filter2d::mrf(
const ImgReaderGdal& input,
ImgWriterGdal& output,
int dimX,
int dimY,
double beta,
bool eightConnectivity,
short down,
bool verbose){
702 assert(m_class.size()>1);
704 for(
int iclass1=0;iclass1<m_class.size();++iclass1)
705 for(
int iclass2=0;iclass2<m_class.size();++iclass2)
706 fullBeta[iclass1][iclass2]=beta;
707 mrf(input,output,dimX,dimY,fullBeta,eightConnectivity,down,verbose);
713 const char* pszMessage;
714 void* pProgressArg=NULL;
715 GDALProgressFunc pfnProgress=GDALTermProgress;
717 pfnProgress(progress,pszMessage,pProgressArg);
724 assert(input.nrOfBand()==1);
725 assert(output.nrOfBand()==m_class.size());
726 assert(m_class.size()>1);
727 assert(beta.size()==m_class.size());
731 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
733 input.readData(inBuffer[indexJ],GDT_Int16,abs(j));
735 catch(std::string errorstring){
736 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
740 for(
int y=0;y<input.nrOfRow();++y){
744 inBuffer.erase(inBuffer.begin());
746 if(y+dimY/2<input.nrOfRow()){
749 inBuffer.push_back(inBuffer.back());
751 input.readData(inBuffer[inBuffer.size()-1],GDT_Int16,y+dimY/2);
753 catch(std::string errorstring){
754 std::cerr << errorstring <<
"in line " << y << std::endl;
758 int over=y+dimY/2-input.nrOfRow();
759 int index=(inBuffer.size()-1)-over;
761 assert(index<inBuffer.size());
762 inBuffer.push_back(inBuffer[index]);
765 if((y+1+down/2)%down)
767 for(
int x=0;x<input.nrOfCol();++x){
768 if((x+1+down/2)%down)
770 std::vector<short> potential(m_class.size());
771 for(
int iclass=0;iclass<m_class.size();++iclass){
773 outBuffer[iclass][x/down]=0;
775 std::vector<double> windowBuffer;
776 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
777 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
778 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
779 if(i!=0&&j!=0&&!eightConnectivity)
787 else if(indexI>=input.nrOfCol())
788 indexI=input.nrOfCol()-i;
791 else if(y+j>=input.nrOfRow())
792 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
796 for(
int imask=0;imask<m_noDataValues.size();++imask){
797 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
803 for(
int iclass=0;iclass<m_class.size();++iclass){
804 if(inBuffer[indexJ][indexI]==m_class[iclass])
805 potential[iclass]+=1;
811 for(
int iclass1=0;iclass1<m_class.size();++iclass1){
812 assert(beta[iclass1].size()==m_class.size());
814 for(
int iclass2=0;iclass2<m_class.size();++iclass2)
816 pot+=potential[iclass2]*beta[iclass1][iclass2];
817 double prior=exp(-pot);
818 outBuffer[iclass1][x/down]=prior;
822 for(
int iclass1=0;iclass1<m_class.size();++iclass1)
823 outBuffer[iclass1][x/down]/=norm;
826 progress=(1.0+y/down)/output.nrOfRow();
827 pfnProgress(progress,pszMessage,pProgressArg);
829 assert(outBuffer.size()==m_class.size());
830 assert(y<output.nrOfRow());
831 for(
int iclass=0;iclass<m_class.size();++iclass){
832 assert(outBuffer[iclass].size()==output.nrOfCol());
834 output.writeData(outBuffer[iclass],GDT_Float64,y/down,iclass);
836 catch(std::string errorstring){
837 std::cerr << errorstring <<
"in class " << iclass <<
", line " << y << std::endl;
843 void filter2d::Filter2d::shift(
const ImgReaderGdal& input,
ImgWriterGdal& output,
double offsetX,
double offsetY,
double randomSigma, RESAMPLE resample,
bool verbose)
845 assert(input.nrOfCol()==output.nrOfCol());
846 assert(input.nrOfRow()==output.nrOfRow());
847 assert(input.nrOfBand()==output.nrOfBand());
848 const char* pszMessage;
849 void* pProgressArg=NULL;
850 GDALProgressFunc pfnProgress=GDALTermProgress;
852 pfnProgress(progress,pszMessage,pProgressArg);
856 for(
int iband=0;iband<input.nrOfBand();++iband){
857 input.readDataBlock(inBuffer,GDT_Float64,0,inBuffer.nCols()-1,0,inBuffer.nRows()-1,iband);
858 shift(inBuffer,outBuffer,offsetX,offsetY,randomSigma,resample,verbose);
859 output.writeDataBlock(outBuffer,GDT_Float64,0,outBuffer.nCols()-1,0,outBuffer.nRows()-1,iband);
970 void filter2d::Filter2d::morphology(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dimX,
int dimY,
const std::vector<double> &angle,
bool disc)
972 const char* pszMessage;
973 void* pProgressArg=NULL;
974 GDALProgressFunc pfnProgress=GDALTermProgress;
976 pfnProgress(progress,pszMessage,pProgressArg);
982 for(
int iband=0;iband<input.nrOfBand();++iband){
984 std::vector<double> outBuffer(input.nrOfCol());
988 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
990 input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
993 catch(std::string errorstring){
994 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
997 for(
int y=0;y<input.nrOfRow();++y){
1001 inBuffer.erase(inBuffer.begin());
1003 if(y+dimY/2<input.nrOfRow()){
1006 inBuffer.push_back(inBuffer.back());
1008 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
1010 catch(std::string errorstring){
1011 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
1015 int over=y+dimY/2-input.nrOfRow();
1016 int index=(inBuffer.size()-1)-over;
1018 assert(index<inBuffer.size());
1019 inBuffer.push_back(inBuffer[index]);
1022 for(
int x=0;x<input.nrOfCol();++x){
1023 double currentValue=inBuffer[(dimY-1)/2][x];
1024 outBuffer[x]=currentValue;
1025 std::vector<double> statBuffer;
1026 bool currentMasked=
false;
1027 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
1028 for(
int imask=0;imask<m_noDataValues.size();++imask){
1029 if(currentValue==m_noDataValues[imask]){
1035 outBuffer[x]=currentValue;
1038 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
1039 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
1041 if(disc&&(d2>(dimX/2)*(dimY/2)))
1048 theta=atan(static_cast<double>(-j)/(static_cast<double>(i)));
1050 theta=-atan(static_cast<double>(j)/(static_cast<double>(i)));
1054 theta=PI-atan(static_cast<double>(-j)/(static_cast<double>(-i)));
1056 theta=PI+atan(static_cast<double>(j)/(static_cast<double>(-i)));
1063 theta=360-(theta/PI*180)+90;
1068 bool alligned=
false;
1069 for(
int iangle=0;iangle<angle.size();++iangle){
1070 if(sqrt((theta-angle[iangle])*(theta-angle[iangle]))<10){
1082 else if(indexI>=input.nrOfCol())
1083 indexI=input.nrOfCol()-i;
1086 else if(y+j>=input.nrOfRow())
1087 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
1089 indexJ=(dimY-1)/2+j;
1094 for(
int imask=0;imask<m_noDataValues.size();++imask){
1095 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
1102 for(
int iclass=0;iclass<m_class.size();++iclass){
1103 if(inBuffer[indexJ][indexI]==m_class[iclass]){
1109 statBuffer.push_back(binValue);
1111 statBuffer.push_back(inBuffer[indexJ][indexI]);
1115 if(statBuffer.size()){
1116 switch(getFilterType(method)){
1117 case(filter2d::dilate):
1118 outBuffer[x]=stat.mymax(statBuffer);
1120 case(filter2d::erode):
1121 outBuffer[x]=stat.mymin(statBuffer);
1124 std::ostringstream ess;
1125 ess <<
"Error: morphology method " << method <<
" not supported, choose " << filter2d::dilate <<
" (dilate) or " << filter2d::erode <<
" (erode)" << std::endl;
1130 if(outBuffer[x]&&m_class.size())
1131 outBuffer[x]=m_class[0];
1136 output.writeData(outBuffer,GDT_Float64,y,iband);
1138 catch(std::string errorstring){
1139 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
1142 progress+=(output.nrOfRow()*iband);
1143 progress/=output.nrOfBand()*output.nrOfRow();
1144 pfnProgress(progress,pszMessage,pProgressArg);
1149 void filter2d::Filter2d::shadowDsm(
const ImgReaderGdal& input,
ImgWriterGdal& output,
double sza,
double saa,
double pixelSize,
short shadowFlag){
1152 input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, 0);
1153 shadowDsm(inputBuffer, outputBuffer, sza, saa, pixelSize, shadowFlag);
1154 output.writeDataBlock(outputBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,0);
1157 void filter2d::Filter2d::dwtForward(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
1159 for(
int iband=0;iband<input.nrOfBand();++iband){
1160 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1161 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1162 dwtForward(theBuffer, wavelet_type, family);
1163 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1167 void filter2d::Filter2d::dwtInverse(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
1169 for(
int iband=0;iband<input.nrOfBand();++iband){
1170 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1171 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1172 dwtInverse(theBuffer, wavelet_type, family);
1173 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1177 void filter2d::Filter2d::dwtCut(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family,
double cut,
bool verbose){
1179 for(
int iband=0;iband<input.nrOfBand();++iband){
1180 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1181 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1182 dwtCut(theBuffer, wavelet_type, family, cut);
1183 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1187 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){
1189 std::vector< Vector2d<float> > outputBuffer;
1190 input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, band);
1192 maxDistance=sqrt(static_cast<float>(input.nrOfCol()*input.nrOfRow()));
1193 linearFeature(inputBuffer,outputBuffer,angle,angleStep,maxDistance,eps, l1, a1, l2, a2,verbose);
1194 for(
int iband=0;iband<outputBuffer.size();++iband)
1195 output.writeDataBlock(outputBuffer[iband],GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1198 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)
1210 output.resize(nband);
1211 for(
int iband=0;iband<output.size();++iband)
1212 output[iband].resize(input.nRows(),input.nCols());
1214 maxDistance=sqrt(static_cast<float>(input.nRows()*input.nCols()));
1217 const char* pszMessage;
1218 void* pProgressArg=NULL;
1219 GDALProgressFunc pfnProgress=GDALTermProgress;
1221 pfnProgress(progress,pszMessage,pProgressArg);
1222 for(
int y=0;y<input.nRows();++y){
1223 for(
int x=0;x<input.nCols();++x){
1224 float currentValue=input[y][x];
1227 float lineDistance1=0;
1228 float lineDistance2=maxDistance;
1232 for(northAngle=0;northAngle<180;northAngle+=angleStep){
1233 if(angle<=360&&angle>=0&&angle!=northAngle)
1237 std::cout <<
"northAngle: " << northAngle << std::endl;
1238 float currentDistance=0;
1240 for(
short side=0;side<=1;side+=1){
1241 theDir=PI/2.0-DEG2RAD(northAngle)+side*PI;
1244 std::cout <<
"theDir in deg: " << RAD2DEG(theDir) << std::endl;
1249 std::cout <<
"theDir in deg: " << RAD2DEG(theDir) << std::endl;
1250 float nextValue=currentValue;
1251 for(
float currentRay=1;currentRay<maxDistance;++currentRay){
1252 indexI=x+currentRay*cos(theDir);
1253 indexJ=y-currentRay*sin(theDir);
1254 if(indexJ<0||indexJ>=input.size())
1256 if(indexI<0||indexI>=input[indexJ].size())
1258 nextValue=input[indexJ][indexI];
1260 std::cout <<
"x: " << x << std::endl;
1261 std::cout <<
"y: " << y << std::endl;
1262 std::cout <<
"currentValue: " << currentValue << std::endl;
1263 std::cout <<
"theDir in degrees: " << RAD2DEG(theDir) << std::endl;
1264 std::cout <<
"cos(theDir): " << cos(theDir) << std::endl;
1265 std::cout <<
"sin(theDir): " << sin(theDir) << std::endl;
1266 std::cout <<
"currentRay: " << currentRay << std::endl;
1267 std::cout <<
"currentDistance: " << currentDistance << std::endl;
1268 std::cout <<
"indexI: " << indexI << std::endl;
1269 std::cout <<
"indexJ: " << indexJ << std::endl;
1270 std::cout <<
"nextValue: " << nextValue << std::endl;
1272 if(fabs(currentValue-nextValue)<=eps){
1276 std::cout <<
"currentDistance: " << currentDistance <<
", continue" << std::endl;
1280 std::cout <<
"currentDistance: " << currentDistance <<
", break" << std::endl;
1285 if(lineDistance1<currentDistance){
1286 lineDistance1=currentDistance;
1287 lineAngle1=northAngle;
1289 if(lineDistance2>currentDistance){
1290 lineDistance2=currentDistance;
1291 lineAngle2=northAngle;
1294 std::cout <<
"lineDistance1: " << lineDistance1 << std::endl;
1295 std::cout <<
"lineAngle1: " << lineAngle1 << std::endl;
1296 std::cout <<
"lineDistance2: " << lineDistance2 << std::endl;
1297 std::cout <<
"lineAngle2: " << lineAngle2 << std::endl;
1302 output[iband++][y][x]=lineDistance1;
1304 output[iband++][y][x]=lineAngle1;
1306 output[iband++][y][x]=lineDistance2;
1308 output[iband++][y][x]=lineAngle2;
1309 assert(iband==nband);
1312 progress/=input.nRows();
1313 pfnProgress(progress,pszMessage,pProgressArg);