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){
111 inBuffer.erase(inBuffer.begin());
113 if(y+dimY/2<input.nrOfRow()){
115 inBuffer.push_back(inBuffer.back());
117 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
119 catch(std::string errorstring){
120 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
124 int over=y+dimY/2-input.nrOfRow();
125 int index=(inBuffer.size()-1)-over;
127 assert(index<inBuffer.size());
128 inBuffer.push_back(inBuffer[index]);
131 for(
int x=0;x<input.nrOfCol();++x){
136 for(
int imask=0;imask<m_noDataValues.size();++imask){
137 if(inBuffer[(dimY-1)/2][x]==m_noDataValues[imask]){
143 outBuffer[x]=inBuffer[(dimY-1)/2][x];
147 assert(!noData||masked);
148 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
149 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
155 else if(x>=input.nrOfCol()-(dimX-1)/2)
158 indexJ=(dimY-1)/2+abs(j);
159 else if(y>=input.nrOfRow()-(dimY-1)/2)
160 indexJ=(dimY-1)/2-abs(j);
163 for(
int imask=0;imask<m_noDataValues.size();++imask){
164 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
170 outBuffer[x]+=(m_taps[(dimY-1)/2+j][(dimX-1)/2+i]*inBuffer[indexJ][indexI]);
171 norm+=m_taps[(dimY-1)/2+j][(dimX-1)/2+i];
176 outBuffer[x]=(normalize&&norm)? abs(outBuffer[x])/norm : abs(outBuffer[x]);
177 else if(normalize&&norm!=0)
178 outBuffer[x]=outBuffer[x]/norm;
182 output.writeData(outBuffer,GDT_Float64,y,iband);
184 catch(std::string errorstring){
185 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
188 progress+=(output.nrOfRow()*iband);
189 progress/=output.nrOfBand()*output.nrOfRow();
190 pfnProgress(progress,pszMessage,pProgressArg);
196 void filter2d::Filter2d::majorVoting(
const std::string& inputFilename,
const std::string& outputFilename,
int dim,
const std::vector<int> &prior)
198 const char* pszMessage;
199 void* pProgressArg=NULL;
200 GDALProgressFunc pfnProgress=GDALTermProgress;
202 pfnProgress(progress,pszMessage,pProgressArg);
206 std::cout <<
"no prior information" << std::endl;
210 std::cout <<
"using priors ";
211 for(
int iclass=0;iclass<prior.size();++iclass)
212 std::cout <<
" " << static_cast<short>(prior[iclass]);
213 std::cout << std::endl;
218 input.open(inputFilename);
219 output.open(outputFilename,input);
227 dimX=m_taps[0].size();
235 std::vector<double> outBuffer(input.nrOfCol());
239 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
241 input.readData(inBuffer[indexJ],GDT_Float64,abs(j));
243 catch(std::string errorstring){
244 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
249 for(
int y=0;y<input.nrOfRow();++y){
252 inBuffer.erase(inBuffer.begin());
254 if(y+dimY/2<input.nrOfRow()){
256 inBuffer.push_back(inBuffer.back());
258 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2);
260 catch(std::string errorstring){
261 std::cerr << errorstring <<
"in line" << y << std::endl;
265 int over=y+dimY/2-input.nrOfRow();
266 int index=(inBuffer.size()-1)-over;
268 assert(index<inBuffer.size());
269 inBuffer.push_back(inBuffer[index]);
272 for(
int x=0;x<input.nrOfCol();++x){
274 std::map<int,int> occurrence;
275 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
276 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
277 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
282 else if(indexI>=input.nrOfCol())
283 indexI=input.nrOfCol()-i;
286 else if(y+j>=input.nrOfRow())
287 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
300 occurrence[inBuffer[indexJ][indexI]]+=prior[inBuffer[indexJ][indexI]-1];
303 ++occurrence[inBuffer[indexJ][indexI]];
306 std::map<int,int>::const_iterator maxit=occurrence.begin();
307 for(std::map<int,int>::const_iterator mit=occurrence.begin();mit!=occurrence.end();++mit){
308 if(mit->second>maxit->second)
311 if(occurrence[inBuffer[(dimY-1)/2][x]]<maxit->second)
312 outBuffer[x]=maxit->first;
314 outBuffer[x]=inBuffer[(dimY-1)/2][x];
318 output.writeData(outBuffer,GDT_Float64,y);
320 catch(std::string errorstring){
321 std::cerr << errorstring <<
"in line" << y << std::endl;
323 progress=(1.0+y)/output.nrOfRow();
324 pfnProgress(progress,pszMessage,pProgressArg);
330 void filter2d::Filter2d::median(
const std::string& inputFilename,
const std::string& outputFilename,
int dim,
bool disc)
334 input.open(inputFilename);
335 output.open(outputFilename,input);
336 doit(input,output,
"median",dim,disc);
339 void filter2d::Filter2d::var(
const std::string& inputFilename,
const std::string& outputFilename,
int dim,
bool disc)
343 input.open(inputFilename);
344 output.open(outputFilename,input);
345 doit(input,output,
"var",dim,disc);
348 void filter2d::Filter2d::doit(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dim,
short down,
bool disc)
350 doit(input,output,method,dim,dim,down,disc);
353 void filter2d::Filter2d::doit(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dimX,
int dimY,
short down,
bool disc)
355 const char* pszMessage;
356 void* pProgressArg=NULL;
357 GDALProgressFunc pfnProgress=GDALTermProgress;
359 pfnProgress(progress,pszMessage,pProgressArg);
365 for(
int iband=0;iband<input.nrOfBand();++iband){
367 std::vector<double> outBuffer((input.nrOfCol()+down-1)/down);
371 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
373 input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
375 catch(std::string errorstring){
376 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
380 for(
int y=0;y<input.nrOfRow();++y){
383 inBuffer.erase(inBuffer.begin());
385 if(y+dimY/2<input.nrOfRow()){
387 inBuffer.push_back(inBuffer.back());
389 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
391 catch(std::string errorstring){
392 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
396 int over=y+dimY/2-input.nrOfRow();
397 int index=(inBuffer.size()-1)-over;
399 assert(index<inBuffer.size());
400 inBuffer.push_back(inBuffer[index]);
403 if((y+1+down/2)%down)
405 for(
int x=0;x<input.nrOfCol();++x){
406 if((x+1+down/2)%down)
409 std::vector<double> windowBuffer;
410 std::map<long int,int> occurrence;
411 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
412 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
413 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
415 if(disc&&(d2>(dimX/2)*(dimY/2)))
421 else if(indexI>=input.nrOfCol())
422 indexI=input.nrOfCol()-i;
425 else if(y+j>=input.nrOfRow())
426 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
430 for(
int imask=0;imask<m_noDataValues.size();++imask){
431 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
437 std::vector<short>::const_iterator vit=m_class.begin();
439 ++occurrence[inBuffer[indexJ][indexI]];
441 while(vit!=m_class.end()){
442 if(inBuffer[indexJ][indexI]==*(vit++))
443 ++occurrence[inBuffer[indexJ][indexI]];
446 windowBuffer.push_back(inBuffer[indexJ][indexI]);
450 switch(getFilterType(method)){
451 case(filter2d::median):
452 if(windowBuffer.empty())
453 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
455 outBuffer[x/down]=stat.median(windowBuffer);
457 case(filter2d::var):{
458 if(windowBuffer.empty())
459 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
461 outBuffer[x/down]=stat.var(windowBuffer);
464 case(filter2d::stdev):{
465 if(windowBuffer.empty())
466 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
468 outBuffer[x/down]=sqrt(stat.var(windowBuffer));
471 case(filter2d::mean):{
472 if(windowBuffer.empty())
473 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
475 outBuffer[x/down]=stat.mean(windowBuffer);
478 case(filter2d::min):{
479 if(windowBuffer.empty())
480 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
482 outBuffer[x/down]=stat.mymin(windowBuffer);
485 case(filter2d::ismin):{
486 if(windowBuffer.empty())
487 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
489 outBuffer[x/down]=(stat.mymin(windowBuffer)==windowBuffer[centre])? 1:0;
492 case(filter2d::minmax):{
495 if(windowBuffer.empty())
496 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
498 stat.minmax(windowBuffer,windowBuffer.begin(),windowBuffer.end(),min,max);
502 outBuffer[x/down]=windowBuffer[centre];
506 case(filter2d::max):{
507 if(windowBuffer.empty())
508 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
510 outBuffer[x/down]=stat.mymax(windowBuffer);
513 case(filter2d::ismax):{
514 if(windowBuffer.empty())
515 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
517 outBuffer[x/down]=(stat.mymax(windowBuffer)==windowBuffer[centre])? 1:0;
520 case(filter2d::order):{
521 if(windowBuffer.empty())
522 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
525 double ubound=dimX*dimY;
526 double theMin=stat.mymin(windowBuffer);
527 double theMax=stat.mymax(windowBuffer);
528 double scale=(ubound-lbound)/(theMax-theMin);
529 outBuffer[x/down]=
static_cast<short>(scale*(windowBuffer[centre]-theMin)+lbound);
533 case(filter2d::sum):{
534 outBuffer[x/down]=stat.sum(windowBuffer);
537 case(filter2d::percentile):{
538 assert(m_threshold.size());
539 outBuffer[x/down]=stat.percentile(windowBuffer,windowBuffer.begin(),windowBuffer.end(),m_threshold[0]);
542 case(filter2d::homog):
543 if(occurrence.size()==1)
544 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
546 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
548 case(filter2d::heterog):{
549 if(occurrence.size()==windowBuffer.size())
550 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
552 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
572 case(filter2d::density):{
573 if(windowBuffer.size()){
574 std::vector<short>::const_iterator vit=m_class.begin();
575 while(vit!=m_class.end())
576 outBuffer[x/down]+=100.0*occurrence[*(vit++)]/windowBuffer.size();
579 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
582 case(filter2d::countid):{
583 if(windowBuffer.size())
584 outBuffer[x/down]=occurrence.size();
586 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
589 case(filter2d::mode):{
590 if(occurrence.size()){
591 std::map<long int,int>::const_iterator maxit=occurrence.begin();
592 for(std::map<long int,int>::const_iterator mit=occurrence.begin();mit!=occurrence.end();++mit){
593 if(mit->second>maxit->second)
596 if(occurrence[inBuffer[(dimY-1)/2][x]]<maxit->second)
597 outBuffer[x/down]=maxit->first;
599 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
602 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
605 case(filter2d::threshold):{
606 assert(m_class.size()==m_threshold.size());
607 if(windowBuffer.size()){
608 outBuffer[x/down]=inBuffer[(dimY-1)/2][x];
609 for(
int iclass=0;iclass<m_class.size();++iclass){
610 if(100.0*(occurrence[m_class[iclass]])/windowBuffer.size()>m_threshold[iclass])
611 outBuffer[x/down]=m_class[iclass];
615 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
618 case(filter2d::scramble):{
619 if(windowBuffer.size()){
620 int randomIndex=std::rand()%windowBuffer.size();
621 outBuffer[x/down]=windowBuffer[randomIndex];
624 outBuffer[x/down]=(m_noDataValues.size())? m_noDataValues[0] : 0;
627 case(filter2d::mixed):{
628 enum Type { BF=11, CF=12, MF=13, NF=20, W=30 };
629 double nBF=occurrence[BF];
630 double nCF=occurrence[CF];
631 double nMF=occurrence[MF];
632 double nNF=occurrence[NF];
633 double nW=occurrence[W];
634 if(windowBuffer.size()){
635 if((nBF+nCF+nMF)&&(nBF+nCF+nMF>=nNF+nW)){
636 if(nBF/(nBF+nCF)>=0.75)
637 outBuffer[x/down]=BF;
638 else if(nCF/(nBF+nCF)>=0.75)
639 outBuffer[x/down]=CF;
641 outBuffer[x/down]=MF;
647 outBuffer[x/down]=NF;
651 outBuffer[x/down]=inBuffer[indexJ][indexI];
655 std::ostringstream ess;
656 ess <<
"Error: filter method " << method <<
" not supported" << std::endl;
662 progress=(1.0+y/down);
663 progress+=(output.nrOfRow()*iband);
664 progress/=output.nrOfBand()*output.nrOfRow();
665 pfnProgress(progress,pszMessage,pProgressArg);
668 output.writeData(outBuffer,GDT_Float64,y/down,iband);
670 catch(std::string errorstring){
671 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
675 pfnProgress(1.0,pszMessage,pProgressArg);
678 void filter2d::Filter2d::mrf(
const ImgReaderGdal& input,
ImgWriterGdal& output,
int dimX,
int dimY,
double beta,
bool eightConnectivity,
short down,
bool verbose){
679 assert(m_class.size()>1);
681 for(
int iclass1=0;iclass1<m_class.size();++iclass1)
682 for(
int iclass2=0;iclass2<m_class.size();++iclass2)
683 fullBeta[iclass1][iclass2]=beta;
684 mrf(input,output,dimX,dimY,fullBeta,eightConnectivity,down,verbose);
690 const char* pszMessage;
691 void* pProgressArg=NULL;
692 GDALProgressFunc pfnProgress=GDALTermProgress;
694 pfnProgress(progress,pszMessage,pProgressArg);
701 assert(input.nrOfBand()==1);
702 assert(output.nrOfBand()==m_class.size());
703 assert(m_class.size()>1);
704 assert(beta.size()==m_class.size());
708 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
710 input.readData(inBuffer[indexJ],GDT_Int16,abs(j));
712 catch(std::string errorstring){
713 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
717 for(
int y=0;y<input.nrOfRow();++y){
720 inBuffer.erase(inBuffer.begin());
722 if(y+dimY/2<input.nrOfRow()){
724 inBuffer.push_back(inBuffer.back());
726 input.readData(inBuffer[inBuffer.size()-1],GDT_Int16,y+dimY/2);
728 catch(std::string errorstring){
729 std::cerr << errorstring <<
"in line " << y << std::endl;
733 int over=y+dimY/2-input.nrOfRow();
734 int index=(inBuffer.size()-1)-over;
736 assert(index<inBuffer.size());
737 inBuffer.push_back(inBuffer[index]);
740 if((y+1+down/2)%down)
742 for(
int x=0;x<input.nrOfCol();++x){
743 if((x+1+down/2)%down)
745 std::vector<short> potential(m_class.size());
746 for(
int iclass=0;iclass<m_class.size();++iclass){
748 outBuffer[iclass][x/down]=0;
750 std::vector<double> windowBuffer;
751 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
752 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
753 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
754 if(i!=0&&j!=0&&!eightConnectivity)
762 else if(indexI>=input.nrOfCol())
763 indexI=input.nrOfCol()-i;
766 else if(y+j>=input.nrOfRow())
767 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
771 for(
int imask=0;imask<m_noDataValues.size();++imask){
772 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
778 for(
int iclass=0;iclass<m_class.size();++iclass){
779 if(inBuffer[indexJ][indexI]==m_class[iclass])
780 potential[iclass]+=1;
786 for(
int iclass1=0;iclass1<m_class.size();++iclass1){
787 assert(beta[iclass1].size()==m_class.size());
789 for(
int iclass2=0;iclass2<m_class.size();++iclass2)
791 pot+=potential[iclass2]*beta[iclass1][iclass2];
792 double prior=exp(-pot);
793 outBuffer[iclass1][x/down]=prior;
797 for(
int iclass1=0;iclass1<m_class.size();++iclass1)
798 outBuffer[iclass1][x/down]/=norm;
801 progress=(1.0+y/down)/output.nrOfRow();
802 pfnProgress(progress,pszMessage,pProgressArg);
804 assert(outBuffer.size()==m_class.size());
805 assert(y<output.nrOfRow());
806 for(
int iclass=0;iclass<m_class.size();++iclass){
807 assert(outBuffer[iclass].size()==output.nrOfCol());
809 output.writeData(outBuffer[iclass],GDT_Float64,y/down,iclass);
811 catch(std::string errorstring){
812 std::cerr << errorstring <<
"in class " << iclass <<
", line " << y << std::endl;
818 void filter2d::Filter2d::shift(
const ImgReaderGdal& input,
ImgWriterGdal& output,
double offsetX,
double offsetY,
double randomSigma, RESAMPLE resample,
bool verbose)
820 assert(input.nrOfCol()==output.nrOfCol());
821 assert(input.nrOfRow()==output.nrOfRow());
822 assert(input.nrOfBand()==output.nrOfBand());
823 const char* pszMessage;
824 void* pProgressArg=NULL;
825 GDALProgressFunc pfnProgress=GDALTermProgress;
827 pfnProgress(progress,pszMessage,pProgressArg);
831 for(
int iband=0;iband<input.nrOfBand();++iband){
832 input.readDataBlock(inBuffer,GDT_Float64,0,inBuffer.nCols()-1,0,inBuffer.nRows()-1,iband);
833 shift(inBuffer,outBuffer,offsetX,offsetY,randomSigma,resample,verbose);
834 output.writeDataBlock(outBuffer,GDT_Float64,0,outBuffer.nCols()-1,0,outBuffer.nRows()-1,iband);
945 void filter2d::Filter2d::morphology(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dimX,
int dimY,
const std::vector<double> &angle,
bool disc)
947 const char* pszMessage;
948 void* pProgressArg=NULL;
949 GDALProgressFunc pfnProgress=GDALTermProgress;
951 pfnProgress(progress,pszMessage,pProgressArg);
957 for(
int iband=0;iband<input.nrOfBand();++iband){
959 std::vector<double> outBuffer(input.nrOfCol());
963 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
965 input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
968 catch(std::string errorstring){
969 std::cerr << errorstring <<
"in line " << indexJ << std::endl;
972 for(
int y=0;y<input.nrOfRow();++y){
975 inBuffer.erase(inBuffer.begin());
977 if(y+dimY/2<input.nrOfRow()){
979 inBuffer.push_back(inBuffer.back());
981 input.readData(inBuffer[inBuffer.size()-1],GDT_Float64,y+dimY/2,iband);
983 catch(std::string errorstring){
984 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
988 int over=y+dimY/2-input.nrOfRow();
989 int index=(inBuffer.size()-1)-over;
991 assert(index<inBuffer.size());
992 inBuffer.push_back(inBuffer[index]);
995 for(
int x=0;x<input.nrOfCol();++x){
996 double currentValue=inBuffer[(dimY-1)/2][x];
997 outBuffer[x]=currentValue;
998 std::vector<double> statBuffer;
999 bool currentMasked=
false;
1000 int centre=dimX*(dimY-1)/2+(dimX-1)/2;
1001 for(
int imask=0;imask<m_noDataValues.size();++imask){
1002 if(currentValue==m_noDataValues[imask]){
1008 outBuffer[x]=currentValue;
1011 for(
int j=-(dimY-1)/2;j<=dimY/2;++j){
1012 for(
int i=-(dimX-1)/2;i<=dimX/2;++i){
1014 if(disc&&(d2>(dimX/2)*(dimY/2)))
1021 theta=atan(static_cast<double>(-j)/(static_cast<double>(i)));
1023 theta=-atan(static_cast<double>(j)/(static_cast<double>(i)));
1027 theta=PI-atan(static_cast<double>(-j)/(static_cast<double>(-i)));
1029 theta=PI+atan(static_cast<double>(j)/(static_cast<double>(-i)));
1036 theta=360-(theta/PI*180)+90;
1041 bool alligned=
false;
1042 for(
int iangle=0;iangle<angle.size();++iangle){
1043 if(sqrt((theta-angle[iangle])*(theta-angle[iangle]))<10){
1055 else if(indexI>=input.nrOfCol())
1056 indexI=input.nrOfCol()-i;
1059 else if(y+j>=input.nrOfRow())
1060 indexJ=(dimY>2) ? (dimY-1)/2-j : 0;
1062 indexJ=(dimY-1)/2+j;
1067 for(
int imask=0;imask<m_noDataValues.size();++imask){
1068 if(inBuffer[indexJ][indexI]==m_noDataValues[imask]){
1075 for(
int iclass=0;iclass<m_class.size();++iclass){
1076 if(inBuffer[indexJ][indexI]==m_class[iclass]){
1082 statBuffer.push_back(binValue);
1084 statBuffer.push_back(inBuffer[indexJ][indexI]);
1088 if(statBuffer.size()){
1089 switch(getFilterType(method)){
1090 case(filter2d::dilate):
1091 outBuffer[x]=stat.mymax(statBuffer);
1093 case(filter2d::erode):
1094 outBuffer[x]=stat.mymin(statBuffer);
1097 std::ostringstream ess;
1098 ess <<
"Error: morphology method " << method <<
" not supported, choose " << filter2d::dilate <<
" (dilate) or " << filter2d::erode <<
" (erode)" << std::endl;
1103 if(outBuffer[x]&&m_class.size())
1104 outBuffer[x]=m_class[0];
1109 output.writeData(outBuffer,GDT_Float64,y,iband);
1111 catch(std::string errorstring){
1112 std::cerr << errorstring <<
"in band " << iband <<
", line " << y << std::endl;
1115 progress+=(output.nrOfRow()*iband);
1116 progress/=output.nrOfBand()*output.nrOfRow();
1117 pfnProgress(progress,pszMessage,pProgressArg);
1122 void filter2d::Filter2d::shadowDsm(
const ImgReaderGdal& input,
ImgWriterGdal& output,
double sza,
double saa,
double pixelSize,
short shadowFlag){
1125 input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, 0);
1126 shadowDsm(inputBuffer, outputBuffer, sza, saa, pixelSize, shadowFlag);
1127 output.writeDataBlock(outputBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,0);
1130 void filter2d::Filter2d::dwtForward(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
1132 for(
int iband=0;iband<input.nrOfBand();++iband){
1133 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1134 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1135 dwtForward(theBuffer, wavelet_type, family);
1136 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1140 void filter2d::Filter2d::dwtInverse(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
1142 for(
int iband=0;iband<input.nrOfBand();++iband){
1143 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1144 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1145 dwtInverse(theBuffer, wavelet_type, family);
1146 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1150 void filter2d::Filter2d::dwtCut(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family,
double cut,
bool verbose){
1152 for(
int iband=0;iband<input.nrOfBand();++iband){
1153 input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
1154 std::cout <<
"filtering band " << iband << std::endl << std::flush;
1155 dwtCut(theBuffer, wavelet_type, family, cut);
1156 output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1160 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){
1162 std::vector< Vector2d<float> > outputBuffer;
1163 input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, band);
1165 maxDistance=sqrt(static_cast<float>(input.nrOfCol()*input.nrOfRow()));
1166 linearFeature(inputBuffer,outputBuffer,angle,angleStep,maxDistance,eps, l1, a1, l2, a2,verbose);
1167 for(
int iband=0;iband<outputBuffer.size();++iband)
1168 output.writeDataBlock(outputBuffer[iband],GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
1171 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)
1183 output.resize(nband);
1184 for(
int iband=0;iband<output.size();++iband)
1185 output[iband].resize(input.nRows(),input.nCols());
1187 maxDistance=sqrt(static_cast<float>(input.nRows()*input.nCols()));
1190 const char* pszMessage;
1191 void* pProgressArg=NULL;
1192 GDALProgressFunc pfnProgress=GDALTermProgress;
1194 pfnProgress(progress,pszMessage,pProgressArg);
1195 for(
int y=0;y<input.nRows();++y){
1196 for(
int x=0;x<input.nCols();++x){
1197 float currentValue=input[y][x];
1200 float lineDistance1=0;
1201 float lineDistance2=maxDistance;
1205 for(northAngle=0;northAngle<180;northAngle+=angleStep){
1206 if(angle<=360&&angle>=0&&angle!=northAngle)
1210 std::cout <<
"northAngle: " << northAngle << std::endl;
1211 float currentDistance=0;
1213 for(
short side=0;side<=1;side+=1){
1214 theDir=PI/2.0-DEG2RAD(northAngle)+side*PI;
1217 std::cout <<
"theDir in deg: " << RAD2DEG(theDir) << std::endl;
1222 std::cout <<
"theDir in deg: " << RAD2DEG(theDir) << std::endl;
1223 float nextValue=currentValue;
1224 for(
float currentRay=1;currentRay<maxDistance;++currentRay){
1225 indexI=x+currentRay*cos(theDir);
1226 indexJ=y-currentRay*sin(theDir);
1227 if(indexJ<0||indexJ>=input.size())
1229 if(indexI<0||indexI>=input[indexJ].size())
1231 nextValue=input[indexJ][indexI];
1233 std::cout <<
"x: " << x << std::endl;
1234 std::cout <<
"y: " << y << std::endl;
1235 std::cout <<
"currentValue: " << currentValue << std::endl;
1236 std::cout <<
"theDir in degrees: " << RAD2DEG(theDir) << std::endl;
1237 std::cout <<
"cos(theDir): " << cos(theDir) << std::endl;
1238 std::cout <<
"sin(theDir): " << sin(theDir) << std::endl;
1239 std::cout <<
"currentRay: " << currentRay << std::endl;
1240 std::cout <<
"currentDistance: " << currentDistance << std::endl;
1241 std::cout <<
"indexI: " << indexI << std::endl;
1242 std::cout <<
"indexJ: " << indexJ << std::endl;
1243 std::cout <<
"nextValue: " << nextValue << std::endl;
1245 if(fabs(currentValue-nextValue)<=eps){
1249 std::cout <<
"currentDistance: " << currentDistance <<
", continue" << std::endl;
1253 std::cout <<
"currentDistance: " << currentDistance <<
", break" << std::endl;
1258 if(lineDistance1<currentDistance){
1259 lineDistance1=currentDistance;
1260 lineAngle1=northAngle;
1262 if(lineDistance2>currentDistance){
1263 lineDistance2=currentDistance;
1264 lineAngle2=northAngle;
1267 std::cout <<
"lineDistance1: " << lineDistance1 << std::endl;
1268 std::cout <<
"lineAngle1: " << lineAngle1 << std::endl;
1269 std::cout <<
"lineDistance2: " << lineDistance2 << std::endl;
1270 std::cout <<
"lineAngle2: " << lineAngle2 << std::endl;
1275 output[iband++][y][x]=lineDistance1;
1277 output[iband++][y][x]=lineAngle1;
1279 output[iband++][y][x]=lineDistance2;
1281 output[iband++][y][x]=lineAngle2;
1282 assert(iband==nband);
1285 progress/=input.nRows();
1286 pfnProgress(progress,pszMessage,pProgressArg);