[pktools] 118/375: added support for discrete wavelet transform in filters
Bas Couwenberg
sebastic at xs4all.nl
Wed Dec 3 21:54:05 UTC 2014
This is an automated email from the git hooks/post-receive script.
sebastic-guest pushed a commit to branch upstream-master
in repository pktools.
commit f659640027f027ed00dec14753180ed478beb0e5
Author: Pieter Kempeneers <kempenep at gmail.com>
Date: Tue Jul 9 10:43:46 2013 +0200
added support for discrete wavelet transform in filters
---
src/algorithms/Filter.cc | 43 +++++++++-------
src/algorithms/Filter.h | 25 ++++-----
src/algorithms/Filter2d.cc | 19 +++++++
src/algorithms/Filter2d.h | 106 +++++++++++++++++++++++++++++++++++++-
src/apps/Makefile.am | 4 +-
src/apps/pkcrop.cc | 6 +--
src/apps/pkextract.cc | 50 +++++++++---------
src/apps/pkfilter.cc | 14 +++++
src/apps/pkfilterascii.cc | 61 +++++++++++++++-------
src/apps/pkinfo.cc | 70 +++++++++++++------------
src/imageclasses/ImgReaderGdal.cc | 39 ++++++++++++++
src/imageclasses/ImgReaderGdal.h | 1 +
src/imageclasses/Makefile.am | 4 +-
13 files changed, 325 insertions(+), 117 deletions(-)
diff --git a/src/algorithms/Filter.cc b/src/algorithms/Filter.cc
index fc7cb2d..56d3bf0 100644
--- a/src/algorithms/Filter.cc
+++ b/src/algorithms/Filter.cc
@@ -19,6 +19,7 @@ along with pktools. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************/
#include "Filter.h"
#include <assert.h>
+#include <math.h>
#include <iostream>
filter::Filter::Filter(void)
@@ -38,25 +39,31 @@ void filter::Filter::setTaps(const vector<double> &taps)
assert(m_taps.size()%2);
}
-// void filter::Filter::dwtForward(std::vector<double>& data, const std::string& wavelet_type, int family){
-// int nsize=data.size();
-// assert(nsize);
-// gsl_wavelet *w;
-// gsl_wavelet_workspace *work;
-// w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
-// work=gsl_wavelet_workspace_alloc(nsize);
-// gsl_wavelet_transform_forward(w,&(data[0]),1,nsize,work);
-// }
+void filter::Filter::dwtForward(std::vector<double>& data, const std::string& wavelet_type, int family){
+ //make sure data size if power of 2
+ while(data.size()&(data.size()-1))
+ data.push_back(data.back());
+ int nsize=data.size();
+ gsl_wavelet *w;
+ gsl_wavelet_workspace *work;
+ assert(nsize);
+ w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
+ work=gsl_wavelet_workspace_alloc(nsize);
+ gsl_wavelet_transform_forward(w,&(data[0]),1,nsize,work);
+}
-// void filter::Filter::dwtInverse(std::vector<double>& data, const std::string& wavelet_type, int family){
-// int nsize=data.size();
-// assert(nsize);
-// gsl_wavelet *w;
-// gsl_wavelet_workspace *work;
-// w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
-// work=gsl_wavelet_workspace_alloc(nsize);
-// gsl_wavelet_transform_inverse(w,&(data[0]),1,nsize,work);
-// }
+void filter::Filter::dwtInverse(std::vector<double>& data, const std::string& wavelet_type, int family){
+ //make sure data size if power of 2
+ while(data.size()&(data.size()-1))
+ data.push_back(data.back());
+ int nsize=data.size();
+ assert(nsize);
+ gsl_wavelet *w;
+ gsl_wavelet_workspace *work;
+ w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
+ work=gsl_wavelet_workspace_alloc(nsize);
+ gsl_wavelet_transform_inverse(w,&(data[0]),1,nsize,work);
+}
void filter::Filter::morphology(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& method, int dim, short down, int offset)
{
diff --git a/src/algorithms/Filter.h b/src/algorithms/Filter.h
index ef89a01..1b6d30e 100644
--- a/src/algorithms/Filter.h
+++ b/src/algorithms/Filter.h
@@ -31,7 +31,7 @@ using namespace std;
namespace filter
{
- enum FILTER_TYPE { median=0, var=1 , min=2, max=3, sum=4, mean=5, minmax=6, dilate=7, erode=8, close=9, open=10, homog=11, sobelx=12, sobely=13, sobelxy=14, sobelyx=-14, smooth=15, density=16, majority=17, mixed=18, smoothnodata=19, threshold=20, ismin=21, ismax=22, heterog=23, order=24, stdev=25, dwtForward=26, dwtInverse=27};
+ enum FILTER_TYPE { median=0, var=1 , min=2, max=3, sum=4, mean=5, minmax=6, dilate=7, erode=8, close=9, open=10, homog=11, sobelx=12, sobely=13, sobelxy=14, sobelyx=-14, smooth=15, density=16, majority=17, mixed=18, smoothnodata=19, threshold=20, ismin=21, ismax=22, heterog=23, order=24, stdev=25, dwtForward=26, dwtInverse=27, dwtQuantize=28};
class Filter
{
@@ -40,9 +40,12 @@ public:
Filter(const vector<double> &taps);
virtual ~Filter(){};
static const gsl_wavelet_type* getWaveletType(const std::string waveletType){
- std::map<std::string, const gsl_wavelet_type* > m_waveletMap;
- initWaveletMap(m_waveletMap);
- return m_waveletMap[waveletType];
+ if(waveletType=="daubechies") return(gsl_wavelet_daubechies);
+ if(waveletType=="daubechies_centered") return(gsl_wavelet_daubechies_centered);
+ if(waveletType=="haar") return(gsl_wavelet_haar);
+ if(waveletType=="haar_centered") return(gsl_wavelet_haar_centered);
+ if(waveletType=="bspline") return(gsl_wavelet_bspline);
+ if(waveletType=="bspline_centered") return(gsl_wavelet_bspline_centered);
}
static FILTER_TYPE getFilterType(const std::string filterType){
std::map<std::string, FILTER_TYPE> m_filterMap;
@@ -63,24 +66,16 @@ public:
template<class T> void applyFwhm(const vector<double> &wavelengthIn, const vector<T>& input, const vector<double> &wavelengthOut, const vector<double> &fwhm, const std::string& interpolationType, vector<T>& output, bool verbose=false);
template<class T> void applyFwhm(const vector<double> &wavelengthIn, const Vector2d<T>& input, const vector<double> &wavelengthOut, const vector<double> &fwhm, const std::string& interpolationType, Vector2d<T>& output, int down=1, bool verbose=false);
- // void dwtForward(std::vector<double>& data, const std::string& wavelet_type, int family);
- // void dwtInverse(std::vector<double>& data, const std::string& wavelet_type, int family);
+ void dwtForward(std::vector<double>& data, const std::string& wavelet_type, int family);
+ void dwtInverse(std::vector<double>& data, const std::string& wavelet_type, int family);
private:
- static void initWaveletMap(std::map<std::string, const gsl_wavelet_type*> m_waveletMap){
- //initialize Map
- m_waveletMap["daubechies"]=gsl_wavelet_daubechies;
- m_waveletMap["daubechies_centered"]=gsl_wavelet_daubechies_centered;
- m_waveletMap["haar"]=gsl_wavelet_haar;
- m_waveletMap["haar_centered"]=gsl_wavelet_haar_centered;
- m_waveletMap["bspline"]=gsl_wavelet_bspline;
- m_waveletMap["bspline_centered"]=gsl_wavelet_bspline_centered;
- }
static void initFilterMap(std::map<std::string, FILTER_TYPE>& m_filterMap){
//initialize Map
m_filterMap["dwtForward"]=filter::dwtForward;
m_filterMap["dwtInverse"]=filter::dwtInverse;
+ m_filterMap["dwtQuantize"]=filter::dwtQuantize;
m_filterMap["stdev"]=filter::stdev;
m_filterMap["var"]=filter::var;
m_filterMap["min"]=filter::min;
diff --git a/src/algorithms/Filter2d.cc b/src/algorithms/Filter2d.cc
index 11a2d88..3cb5e73 100644
--- a/src/algorithms/Filter2d.cc
+++ b/src/algorithms/Filter2d.cc
@@ -1106,3 +1106,22 @@ void filter2d::Filter2d::shadowDsm(const ImgReaderGdal& input, ImgWriterGdal& ou
shadowDsm(inputBuffer, outputBuffer, sza, saa, pixelSize, shadowFlag);
output.writeDataBlock(outputBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,0);
}
+
+void filter2d::Filter2d::dwtForward(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family){
+ Vector2d<float> theBuffer;
+ for(int iband=0;iband<input.nrOfBand();++iband){
+ input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
+ dwtForward(theBuffer, wavelet_type, family);
+ output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
+ }
+}
+
+void filter2d::Filter2d::dwtQuantize(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family, double quantize, bool verbose){
+ Vector2d<float> theBuffer;
+ for(int iband=0;iband<input.nrOfBand();++iband){
+ input.readDataBlock(theBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, iband);
+ std::cout << "filtering band " << iband << std::endl << std::flush;
+ dwtQuantize(theBuffer, wavelet_type, family, quantize);
+ output.writeDataBlock(theBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,iband);
+ }
+}
diff --git a/src/algorithms/Filter2d.h b/src/algorithms/Filter2d.h
index fb2d3ea..b136eac 100644
--- a/src/algorithms/Filter2d.h
+++ b/src/algorithms/Filter2d.h
@@ -34,7 +34,11 @@ along with pktools. If not, see <http://www.gnu.org/licenses/>.
#include <vector>
#include <string>
#include <map>
+#include <gsl/gsl_sort.h>
+#include <gsl/gsl_wavelet.h>
+#include <gsl/gsl_wavelet2d.h>
#include "base/Vector2d.h"
+#include "Filter.h"
#include "imageclasses/ImgReaderGdal.h"
#include "imageclasses/ImgWriterGdal.h"
#include "algorithms/StatFactory.h"
@@ -43,7 +47,7 @@ using namespace std;
// using namespace cimg_library;
namespace filter2d
{
- enum FILTER_TYPE { median=0, var=1 , min=2, max=3, sum=4, mean=5, minmax=6, dilate=7, erode=8, close=9, open=10, homog=11, sobelx=12, sobely=13, sobelxy=14, sobelyx=-14, smooth=15, density=16, majority=17, mixed=18, smoothnodata=19, threshold=20, ismin=21, ismax=22, heterog=23, order=24, stdev=25, mrf=26};
+ enum FILTER_TYPE { median=0, var=1 , min=2, max=3, sum=4, mean=5, minmax=6, dilate=7, erode=8, close=9, open=10, homog=11, sobelx=12, sobely=13, sobelxy=14, sobelyx=-14, smooth=15, density=16, majority=17, mixed=18, smoothnodata=19, threshold=20, ismin=21, ismax=22, heterog=23, order=24, stdev=25, mrf=26, dwtForward=27, dwtInverse=28, dwtQuantize=29};
class Filter2d
{
@@ -72,6 +76,11 @@ public:
template<class T1, class T2> void filter(const Vector2d<T1>& inputVector, Vector2d<T2>& outputVector);
template<class T1, class T2> void smooth(const Vector2d<T1>& inputVector, Vector2d<T2>& outputVector,int dim);
template<class T1, class T2> void smooth(const Vector2d<T1>& inputVector, Vector2d<T2>& outputVector,int dimX, int dimY);
+ void dwtForward(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family);
+ void dwtQuantize(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family, double quantize, bool verbose=false);
+ template<class T> void dwtForward(Vector2d<T>& data, const std::string& wavelet_type, int family);
+ template<class T> void dwtQuantize(Vector2d<T>& data, const std::string& wavelet_type, int family, double quantize);
+ template<class T> void dwtInverse(Vector2d<T>& data, const std::string& wavelet_type, int family);
void majorVoting(const string& inputFilename, const string& outputFilename,int dim=0,const vector<int> &prior=vector<int>());
/* void homogeneousSpatial(const string& inputFilename, const string& outputFilename, int dim, bool disc=false, int noValue=0); */
void doit(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& method, int dim, short down=2, bool disc=false);
@@ -118,6 +127,7 @@ private:
m_filterMap["heterog"]=filter2d::heterog;
m_filterMap["order"]=filter2d::order;
m_filterMap["median"]=filter2d::median;
+ m_filterMap["dwtQuantize"]=filter2d::dwtQuantize;
}
Vector2d<double> m_taps;
@@ -628,6 +638,100 @@ template<class T> unsigned long int Filter2d::morphology(const Vector2d<T>& inpu
}
}
+template<class T> void Filter2d::dwtForward(Vector2d<T>& theBuffer, const std::string& wavelet_type, int family){
+ //make sure data size if power of 2
+ int nRow=theBuffer.size();
+ assert(nRow);
+ int nCol=theBuffer[0].size();
+ assert(nCol);
+ while(theBuffer.size()&(theBuffer.size()-1))
+ theBuffer.push_back(theBuffer.back());
+ for(int irow=0;irow<theBuffer.size();++irow)
+ while(theBuffer[irow].size()&(theBuffer[irow].size()-1))
+ theBuffer[irow].push_back(theBuffer[irow].back());
+ double data[theBuffer.size()*theBuffer[0].size()];
+ for(int irow=0;irow<theBuffer.size();++irow){
+ for(int icol=0;icol<theBuffer[0].size();++icol){
+ int index=irow*theBuffer[0].size()+icol;
+ data[index]=theBuffer[irow][icol];
+ }
+ }
+ int nsize=theBuffer.size()*theBuffer[0].size();
+ gsl_wavelet *w;
+ gsl_wavelet_workspace *work;
+ assert(nsize);
+ w=gsl_wavelet_alloc(filter::Filter::getWaveletType(wavelet_type),family);
+ work=gsl_wavelet_workspace_alloc(nsize);
+ gsl_wavelet2d_nstransform_forward (w, data, theBuffer.size(), theBuffer.size(),theBuffer[0].size(), work);
+ theBuffer.erase(theBuffer.begin()+nRow,theBuffer.end());
+ for(int irow=0;irow<theBuffer.size();++irow){
+ theBuffer[irow].erase(theBuffer[irow].begin()+nCol,theBuffer[irow].end());
+ for(int icol=0;icol<theBuffer[irow].size();++icol){
+ int index=irow*theBuffer[irow].size()+icol;
+ theBuffer[irow][icol]=data[index];
+ }
+ }
+}
+
+template<class T> void Filter2d::dwtQuantize(Vector2d<T>& theBuffer, const std::string& wavelet_type, int family, double quantize){
+ //make sure data size if power of 2
+ int nRow=theBuffer.size();
+ assert(nRow);
+ int nCol=theBuffer[0].size();
+ assert(nCol);
+ while(theBuffer.size()&(theBuffer.size()-1))
+ theBuffer.push_back(theBuffer.back());
+ for(int irow=0;irow<theBuffer.size();++irow)
+ while(theBuffer[irow].size()&(theBuffer[irow].size()-1))
+ theBuffer[irow].push_back(theBuffer[irow].back());
+ double* data=new double[theBuffer.size()*theBuffer[0].size()];
+ double* abscoeff=new double[theBuffer.size()*theBuffer[0].size()];
+ size_t* p=new size_t[theBuffer.size()*theBuffer[0].size()];
+ for(int irow=0;irow<theBuffer.size();++irow){
+ for(int icol=0;icol<theBuffer[0].size();++icol){
+ int index=irow*theBuffer[0].size()+icol;
+ assert(index<theBuffer.size()*theBuffer[0].size());
+ data[index]=theBuffer[irow][icol];
+ }
+ }
+ int nsize=theBuffer.size()*theBuffer[0].size();
+ gsl_wavelet *w;
+ gsl_wavelet_workspace *work;
+ assert(nsize);
+ w=gsl_wavelet_alloc(filter::Filter::getWaveletType(wavelet_type),family);
+ work=gsl_wavelet_workspace_alloc(nsize);
+ gsl_wavelet2d_nstransform_forward (w, data, theBuffer.size(), theBuffer[0].size(),theBuffer[0].size(), work);
+ for(int irow=0;irow<theBuffer.size();++irow){
+ for(int icol=0;icol<theBuffer[0].size();++icol){
+ int index=irow*theBuffer[0].size()+icol;
+ abscoeff[index]=fabs(data[index]);
+ if(quantize<0){//absolute threshold
+ if(abscoeff[index]<-quantize)
+ data[index]=0;
+ }
+ }
+ }
+ if(quantize>0){//percentual threshold
+ int nc=quantize/100.0*nsize;
+ gsl_sort_index(p,abscoeff,1,nsize);
+ for(int i=0;(i+nc)<nsize;i++)
+ data[p[i]]=0;
+ }
+ gsl_wavelet2d_nstransform_inverse (w, data, theBuffer.size(), theBuffer[0].size(),theBuffer[0].size(), work);
+ for(int irow=0;irow<theBuffer.size();++irow){
+ for(int icol=0;icol<theBuffer[irow].size();++icol){
+ int index=irow*theBuffer[irow].size()+icol;
+ theBuffer[irow][icol]=data[index];
+ }
+ }
+ theBuffer.erase(theBuffer.begin()+nRow,theBuffer.end());
+ for(int irow=0;irow<theBuffer.size();++irow)
+ theBuffer[irow].erase(theBuffer[irow].begin()+nCol,theBuffer[irow].end());
+ delete[] data;
+ delete[] abscoeff;
+ delete[] p;
+}
+
}
#endif /* _MYFILTER_H_ */
diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
index 6eeebb2..2de9f1a 100644
--- a/src/apps/Makefile.am
+++ b/src/apps/Makefile.am
@@ -6,7 +6,7 @@ LDADD = $(GDAL_LDFLAGS) $(top_builddir)/src/algorithms/libalgorithms.la $(top_bu
###############################################################################
# the program to build and install (the names of the final binaries)
-bin_PROGRAMS = pkinfo pkcrop pkreclass pkgetmask pksetmask pkcreatect pkdumpimg pkdumpogr pksieve pkstat pkstatogr pkegcs pkextract pkfillnodata pkfilter pkfilterascii pkdsm2shadow pkmosaic pkndvi pkpolygonize pkascii2img pkdiff pkclassify_svm pkfs_svm pkascii2ogr pkeditogr
+bin_PROGRAMS = pkinfo pkcrop pkreclass pkgetmask pksetmask pkcreatect pkdumpimg pkdumpogr pksieve pkstat pkstatogr pkegcs pkextract pkfillnodata pkfilter pkenhance pkfilterascii pkdsm2shadow pkmosaic pkndvi pkpolygonize pkascii2img pkdiff pkclassify_svm pkfs_svm pkascii2ogr pkeditogr
# the program to build but not install (the names of the final binaries)
#noinst_PROGRAMS = pkxcorimg pkgeom
@@ -53,6 +53,8 @@ pkextract_SOURCES = pkextract.cc
pkfillnodata_SOURCES = pkfillnodata.cc
pkfilter_SOURCES = pkfilter.cc
pkfilter_LDADD = $(GSL_LIBS) $(AM_LDFLAGS) -lgsl -lgdal
+pkenhance_SOURCES = pkenhance.cc
+pkenhance_LDADD = $(AM_LDFLAGS) -lgdal
pkfilterascii_SOURCES = pkfilterascii.cc
pkfilterascii_LDADD = $(GSL_LIBS) $(AM_LDFLAGS) -lgsl -lgdal
pkdsm2shadow_SOURCES = pkdsm2shadow.cc
diff --git a/src/apps/pkcrop.cc b/src/apps/pkcrop.cc
index ea65ca2..6f86cb2 100644
--- a/src/apps/pkcrop.cc
+++ b/src/apps/pkcrop.cc
@@ -53,8 +53,8 @@ int main(int argc, char *argv[])
Optionpk<double> offset_opt("off", "offset", "output=scale*input+offset", 0);
Optionpk<string> otype_opt("ot", "otype", "Data type for output image ({Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/CInt16/CInt32/CFloat32/CFloat64}). Empty string: inherit type from input image","");
Optionpk<string> oformat_opt("of", "oformat", "Output image format (see also gdal_translate). Empty string: inherit from input image");
- Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
+ Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
Optionpk<short> flag_opt("f", "flag", "Flag value to put in image if out of bounds.", 0);
Optionpk<string> resample_opt("r", "resampling-method", "Resampling method (near: nearest neighbour, bilinear: bi-linear interpolation).", "near");
Optionpk<string> description_opt("d", "description", "Set image description", "");
@@ -77,6 +77,7 @@ int main(int argc, char *argv[])
offset_opt.retrieveOption(argc,argv);
otype_opt.retrieveOption(argc,argv);
oformat_opt.retrieveOption(argc,argv);
+ option_opt.retrieveOption(argc,argv);
colorTable_opt.retrieveOption(argc,argv);
dx_opt.retrieveOption(argc,argv);
dy_opt.retrieveOption(argc,argv);
@@ -86,7 +87,6 @@ int main(int argc, char *argv[])
ny_opt.retrieveOption(argc,argv);
ns_opt.retrieveOption(argc,argv);
nl_opt.retrieveOption(argc,argv);
- option_opt.retrieveOption(argc,argv);
flag_opt.retrieveOption(argc,argv);
resample_opt.retrieveOption(argc,argv);
description_opt.retrieveOption(argc,argv);
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
exit(0);//help was invoked, stop processing
}
if(output_opt.empty()){
- std::cerr << "No output file provided (use option -i). Use pkinfo --help for help information" << std::endl;
+ std::cerr << "No output file provided (use option -o). Use pkinfo --help for help information" << std::endl;
exit(0);//help was invoked, stop processing
}
diff --git a/src/apps/pkextract.cc b/src/apps/pkextract.cc
index 007c504..90b3028 100644
--- a/src/apps/pkextract.cc
+++ b/src/apps/pkextract.cc
@@ -125,7 +125,7 @@ int main(int argc, char *argv[])
}
short theDim=boundary_opt[0];
if(verbose_opt[0]>1)
- std::cout << boundary_opt[0] << std::endl;
+ std::cout << "boundary: " << boundary_opt[0] << std::endl;
ImgReaderGdal imgReader;
try{
imgReader.open(image_opt[0]);
@@ -398,18 +398,20 @@ int main(int argc, char *argv[])
if(p>theThreshold)
continue;//do not select for now, go to next column
}
- else{//absolute value
+ else if(nvalid.size()>processClass){//absolute value
if(nvalid[processClass]>-theThreshold)
- continue;//do not select any more pixels for this class, go to next column to search for other classes
+ continue;//do not select any more pixels for this class, go to next column to search for other classes
}
writeBuffer.push_back(sample);
writeBufferClass.push_back(theClass);
++ntotalvalid;
- ++(nvalid[processClass]);
+ if(nvalid.size()>processClass)
+ ++(nvalid[processClass]);
}
else{
++ntotalinvalid;
- ++(ninvalid[processClass]);
+ if(ninvalid.size()>processClass)
+ ++(ninvalid[processClass]);
}
}//processClass
}//icol
@@ -468,8 +470,10 @@ int main(int argc, char *argv[])
nsample=writeBuffer.size();
if(verbose_opt[0]){
std::cout << "total number of samples written: " << nsample << std::endl;
- for(int iclass=0;iclass<class_opt.size();++iclass)
- std::cout << "class " << class_opt[iclass] << " has " << nvalid[iclass] << " samples" << std::endl;
+ if(nvalid.size()==class_opt.size()){
+ for(int iclass=0;iclass<class_opt.size();++iclass)
+ std::cout << "class " << class_opt[iclass] << " has " << nvalid[iclass] << " samples" << std::endl;
+ }
}
}
else{//class_opt[0]!=0
@@ -518,7 +522,7 @@ int main(int argc, char *argv[])
int theClass=0;
// double theClass=0;
int processClass=-1;
- if(class_opt[0]<0){//process every class except 0
+ if(class_opt.empty()){//process every class
if(classBuffer[icol]){
processClass=0;
theClass=classBuffer[icol];
@@ -643,7 +647,7 @@ int main(int argc, char *argv[])
if(p>theThreshold)
continue;//do not select for now, go to next column
}
- else{//absolute value
+ else if(nvalid.size()>processClass){//absolute value
if(nvalid[processClass]>-theThreshold)
continue;//do not select any more pixels for this class, go to next column to search for other classes
}
@@ -651,11 +655,13 @@ int main(int argc, char *argv[])
// writeBufferClass.push_back(class_opt[processClass]);
writeBufferClass.push_back(theClass);
++ntotalvalid;
- ++(nvalid[processClass]);
+ if(nvalid.size()>processClass)
+ ++(nvalid[processClass]);
}
else{
++ntotalinvalid;
- ++(ninvalid[processClass]);
+ if(ninvalid.size()>processClass)
+ ++(ninvalid[processClass]);
}
}//processClass
}//icol
@@ -716,8 +722,10 @@ int main(int argc, char *argv[])
nsample=writeBuffer.size();
if(verbose_opt[0]){
std::cout << "total number of samples written: " << nsample << std::endl;
- for(int iclass=0;iclass<class_opt.size();++iclass)
- std::cout << "class " << class_opt[iclass] << " has " << nvalid[iclass] << " samples" << std::endl;
+ if(nvalid.size()==class_opt.size()){
+ for(int iclass=0;iclass<class_opt.size();++iclass)
+ std::cout << "class " << class_opt[iclass] << " has " << nvalid[iclass] << " samples" << std::endl;
+ }
}
}
}
@@ -768,6 +776,7 @@ int main(int argc, char *argv[])
switch(ruleMap[rule_opt[0]]){
// switch(rule_opt[0]){
case(rule::proportion):{//proportion for each class
+ assert(class_opt.size());
for(int iclass=0;iclass<class_opt.size();++iclass){
ostringstream cs;
cs << class_opt[iclass];
@@ -781,9 +790,10 @@ int main(int argc, char *argv[])
case(rule::minimum):
case(rule::maximum):
case(rule::maxvote):
+ assert(class_opt.size());
ogrWriter.createField(label_opt[0],fieldType);
- if(test_opt.size())
- ogrTestWriter.createField(label_opt[0],fieldType);
+ if(test_opt.size())
+ ogrTestWriter.createField(label_opt[0],fieldType);
break;
case(rule::point):
case(rule::mean):
@@ -1218,9 +1228,6 @@ int main(int argc, char *argv[])
imgReader.image2geo(i,j,x,y);
thePoint.setX(x);
thePoint.setY(y);
- // //test
- // writeRing.addPoint(&thePoint);
- // if(thePoint.Within(&readPolygon)){
if(readPolygon.Contains(&thePoint)){
bool valid=true;
for(int imask=0;imask<mask_opt.size();++imask){
@@ -1432,8 +1439,6 @@ int main(int argc, char *argv[])
}
}
}
- // //test
- // std::cout << "before write polygon" << std::endl;
if(polygon_opt[0]||ruleMap[rule_opt[0]]==rule::mean){
//do not create if no points found within polygon
if(!nPointPolygon)
@@ -1832,9 +1837,6 @@ int main(int argc, char *argv[])
imgReader.image2geo(i,j,x,y);
thePoint.setX(x);
thePoint.setY(y);
- // //test
- // writeRing.addPoint(&thePoint);
- // if(thePoint.Within(&readPolygon)){
if(readPolygon.Contains(&thePoint)){
bool valid=true;
for(int imask=0;imask<mask_opt.size();++imask){
@@ -2044,8 +2046,6 @@ int main(int argc, char *argv[])
}
}
}
- // //test
- // std::cout << "before write polygon" << std::endl;
if(polygon_opt[0]||ruleMap[rule_opt[0]]==rule::mean){
//add ring to polygon
if(polygon_opt[0]){
diff --git a/src/apps/pkfilter.cc b/src/apps/pkfilter.cc
index 689cb42..17c46ac 100644
--- a/src/apps/pkfilter.cc
+++ b/src/apps/pkfilter.cc
@@ -45,6 +45,9 @@ int main(int argc,char **argv) {
Optionpk<int> dimX_opt("dx", "dx", "filter kernel size in x, must be odd", 3);
Optionpk<int> dimY_opt("dy", "dy", "filter kernel size in y, must be odd", 3);
Optionpk<int> dimZ_opt("dz", "dz", "filter kernel size in z (band or spectral dimension), must be odd (example: 3).. Set dz>0 if 1-D filter must be used in band domain");
+ Optionpk<std::string> wavelet_type_opt("wt", "wavelet", "wavelet type: daubechies,daubechies_centered, haar, haar_centered, bspline, bspline_centered", "daubechies");
+ Optionpk<int> family_opt("wf", "family", "wavelet family (vanishing moment, see also http://www.gnu.org/software/gsl/manual/html_node/DWT-Initialization.html)", 4);
+ Optionpk<double> quantize_opt("q", "quantize", "Quantize threshold (positive for percentage value, negative for absolute value)",0);
Optionpk<short> class_opt("class", "class", "class value(s) to use for density, erosion, dilation, openening and closing, thresholding");
Optionpk<double> threshold_opt("t", "threshold", "threshold value(s) to use for threshold filter (one for each class)", 0);
Optionpk<short> mask_opt("m", "mask", "mask value(s) ");
@@ -74,6 +77,9 @@ int main(int argc,char **argv) {
dimY_opt.retrieveOption(argc,argv);
dimZ_opt.retrieveOption(argc,argv);
option_opt.retrieveOption(argc,argv);
+ wavelet_type_opt.retrieveOption(argc,argv);
+ family_opt.retrieveOption(argc,argv);
+ quantize_opt.retrieveOption(argc,argv);
class_opt.retrieveOption(argc,argv);
threshold_opt.retrieveOption(argc,argv);
mask_opt.retrieveOption(argc,argv);
@@ -506,6 +512,14 @@ int main(int argc,char **argv) {
filter2d.smoothNoData(input,output,dimX_opt[0],dimY_opt[0]);
break;
}
+ case(filter2d::dwtForward):
+ filter2d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
+ break;
+ case(filter2d::dwtQuantize):
+ if(verbose_opt[0])
+ std::cout << "Quantization filtering" << std::endl;
+ filter2d.dwtQuantize(input, output, wavelet_type_opt[0], family_opt[0], quantize_opt[0]);
+ break;
case(filter2d::threshold):
filter2d.setThresholds(threshold_opt);
filter2d.setClasses(class_opt);//deliberate fall through
diff --git a/src/apps/pkfilterascii.cc b/src/apps/pkfilterascii.cc
index 434a5a0..af3f787 100644
--- a/src/apps/pkfilterascii.cc
+++ b/src/apps/pkfilterascii.cc
@@ -36,9 +36,10 @@ int main(int argc,char **argv) {
Optionpk<std::string> input_opt("i","input","input ASCII file");
Optionpk<std::string> output_opt("o", "output", "Output ASCII file");
Optionpk<int> inputCols_opt("ic", "inputCols", "input columns (e.g., for three dimensional input data in first three columns use: -ic 0 -ic 1 -ic 2");
- Optionpk<std::string> method_opt("f", "filter", "filter function (to be implemented: dwtForward, dwtInverse)");
- Optionpk<std::string> wavelet_type_opt("wt", "wavelet", "wavelet type: daubechies,daubechies_centered, haar, haar_centered, bspline, bspline_centered", "daubechies");
- Optionpk<int> family_opt("wf", "family", "wavelet family (vanishing moment, see also http://www.gnu.org/software/gsl/manual/html_node/DWT-Initialization.html)", 4);
+ Optionpk<std::string> method_opt("f", "filter", "filter function (to be implemented: dwtForward, dwtInverse,dwtQuantize)");
+ Optionpk<std::string> wavelet_type_opt("wt", "wavelet", "wavelet type: daubechies,daubechies_centered, haar, haar_centered, bspline, bspline_centered", "daubechies");
+ Optionpk<int> family_opt("wf", "family", "wavelet family (vanishing moment, see also http://www.gnu.org/software/gsl/manual/html_node/DWT-Initialization.html)", 4);
+ Optionpk<double> quantize_opt("q", "quantize", "Quantize threshold",0);
Optionpk<int> dimZ_opt("dz", "dz", "filter kernel size in z (band or spectral dimension), must be odd (example: 3).. Set dz>0 if 1-D filter must be used in band domain");
Optionpk<double> tapz_opt("tapz", "tapz", "taps used for spectral filtering");
Optionpk<double> fwhm_opt("fwhm", "fwhm", "list of full width half to apply spectral filtering (-fwhm band1 -fwhm band2 ...)");
@@ -55,6 +56,9 @@ int main(int argc,char **argv) {
output_opt.retrieveOption(argc,argv);
inputCols_opt.retrieveOption(argc,argv);
method_opt.retrieveOption(argc,argv);
+ wavelet_type_opt.retrieveOption(argc,argv);
+ family_opt.retrieveOption(argc,argv);
+ quantize_opt.retrieveOption(argc,argv);
dimZ_opt.retrieveOption(argc,argv);
tapz_opt.retrieveOption(argc,argv);
fwhm_opt.retrieveOption(argc,argv);
@@ -158,7 +162,7 @@ int main(int argc,char **argv) {
else{//no filtering
if(verbose_opt[0])
std::cout << "no filtering selected" << std::endl;
- wavelengthOut=wavelengthIn;
+ // wavelengthOut=wavelengthIn;
for(int icol=0;icol<inputCols_opt.size();++icol)
filteredData[icol]=inputData[icol];
}
@@ -166,12 +170,24 @@ int main(int argc,char **argv) {
if(method_opt.size()){
for(int icol=0;icol<inputCols_opt.size();++icol){
switch(filter::Filter::getFilterType(method_opt[0])){
- // case(filter::dwtForward):
- // filter1d.dwtForward(filteredData[icol],wavelet_type_opt[0],family_opt[0]);
- // break;
- // case(filter::dwtInverse):
- // filter1d.dwtInverse(filteredData[icol],wavelet_type_opt[0],family_opt[0]);
- // break;
+ case(filter::dwtForward):
+ filter1d.dwtForward(filteredData[icol],wavelet_type_opt[0],family_opt[0]);
+ break;
+ case(filter::dwtInverse):
+ filter1d.dwtInverse(filteredData[icol],wavelet_type_opt[0],family_opt[0]);
+ break;
+ case(filter::dwtQuantize):{
+ int origSize=filteredData[icol].size();
+ filter1d.dwtForward(filteredData[icol],wavelet_type_opt[0],family_opt[0]);
+ for(int iband=0;iband<filteredData[icol].size();++iband){
+ if(fabs(filteredData[icol][iband])<quantize_opt[0])
+ filteredData[icol][iband]=0;
+ }
+ filter1d.dwtInverse(filteredData[icol],wavelet_type_opt[0],family_opt[0]);
+ //remove extended samples
+ filteredData[icol].erase(filteredData[icol].begin()+origSize,filteredData[icol].end());
+ break;
+ }
default:
if(verbose_opt[0])
std::cout << "method to be implemented" << std::endl;
@@ -185,17 +201,17 @@ int main(int argc,char **argv) {
if(transpose_opt[0]){
for(int icol=0;icol<inputCols_opt.size();++icol){
- for(int iband=0;iband<wavelengthOut.size();++iband){
+ for(int iband=0;iband<filteredData[icol].size();++iband){
if(!output_opt.empty()){
outputStream << filteredData[icol][iband];
- if(iband<wavelengthOut.size()-1)
+ if(iband<filteredData[icol].size()-1)
outputStream << " ";
else
outputStream << std::endl;
}
else{
std::cout << filteredData[icol][iband];
- if(iband<wavelengthOut.size()-1)
+ if(iband<filteredData[icol].size()-1)
std::cout << " ";
else
std::cout << std::endl;
@@ -204,11 +220,20 @@ int main(int argc,char **argv) {
}
}
else{
- for(int iband=0;iband<wavelengthOut.size();++iband){
- if(!output_opt.empty())
- outputStream << wavelengthOut[iband] << " ";
- else
- std::cout << wavelengthOut[iband] << " ";
+ int nband=wavelengthOut.size()? wavelengthOut.size() : filteredData[0].size();
+ for(int iband=0;iband<nband;++iband){
+ if(!output_opt.empty()){
+ if(wavelengthOut.size())
+ outputStream << wavelengthOut[iband] << " ";
+ else
+ outputStream << iband << " ";
+ }
+ else{
+ if(wavelengthOut.size())
+ std::cout << wavelengthOut[iband] << " ";
+ else
+ std::cout << iband << " ";
+ }
for(int icol=0;icol<inputCols_opt.size();++icol){
if(!output_opt.empty()){
outputStream << filteredData[icol][iband];
diff --git a/src/apps/pkinfo.cc b/src/apps/pkinfo.cc
index a8f15ee..cfba529 100644
--- a/src/apps/pkinfo.cc
+++ b/src/apps/pkinfo.cc
@@ -261,44 +261,46 @@ int main(int argc, char *argv[])
}
if(hist_opt[0]){
assert(band_opt[0]<imgReader.nrOfBand());
- imgReader.getMinMax(minValue,maxValue,band_opt[0]);
+ int nbin=nbin_opt[0];
+ // imgReader.getMinMax(minValue,maxValue,band_opt[0]);
+ // if(min_opt.size())
+ // minValue=min_opt[0];
+ // if(max_opt.size())
+ // maxValue=max_opt[0];
+ // if(nbin_opt[0]==0)
+ // nbin=maxValue-minValue+1;
+ // assert(nbin>0);
+ // std::vector<unsigned long int> output(nbin);
+ // unsigned long int nsample=0;
+ // unsigned long int ninvalid=0;
+ // std::vector<double> lineBuffer(imgReader.nrOfCol());
+ // for(int i=0;i<nbin;output[i++]=0);
+ // for(int irow=0;irow<imgReader.nrOfRow();++irow){
+ // imgReader.readData(lineBuffer,GDT_Float64,irow,band_opt[0]);
+ // for(int icol=0;icol<imgReader.nrOfCol();++icol){
+ // if(imgReader.isNoData(lineBuffer[icol]))
+ // ++ninvalid;
+ // else if(lineBuffer[icol]>maxValue)
+ // ++ninvalid;
+ // else if(lineBuffer[icol]<minValue)
+ // ++ninvalid;
+ // else if(lineBuffer[icol]==maxValue)
+ // ++output[nbin-1];
+ // else
+ // ++output[static_cast<int>(static_cast<double>(lineBuffer[icol]-minValue)/(maxValue-minValue)*nbin)];
+ // }
+ // }
+ std::vector<unsigned long int> output(nbin_opt[0]);
+ minValue=0;
+ maxValue=0;
if(min_opt.size())
- minValue=min_opt[0];
+ minValue=min_opt.size();
if(max_opt.size())
- maxValue=max_opt[0];
- int nbin=nbin_opt[0];
- if(nbin_opt[0]==0)
- nbin=maxValue-minValue+1;
- assert(nbin>0);
- std::vector<unsigned long int> output(nbin);
- unsigned long int nsample=0;
- unsigned long int ninvalid=0;
- std::vector<double> lineBuffer(imgReader.nrOfCol());
- for(int i=0;i<nbin;output[i++]=0);
- for(int irow=0;irow<imgReader.nrOfRow();++irow){
- imgReader.readData(lineBuffer,GDT_Float64,irow,band_opt[0]);
- for(int icol=0;icol<imgReader.nrOfCol();++icol){
- if(imgReader.isNoData(lineBuffer[icol]))
- ++ninvalid;
- else if(lineBuffer[icol]>maxValue)
- ++ninvalid;
- else if(lineBuffer[icol]<minValue)
- ++ninvalid;
- else if(lineBuffer[icol]==maxValue)
- ++output[nbin-1];
- // else if(static_cast<double>(lineBuffer[icol]-minValue)/(maxValue-minValue)*nbin>=nbin){
- // //test
- // std::cout << "..." << lineBuffer[icol] << std::endl;
- // ++output[nbin-1];
- // }
- else
- ++output[static_cast<int>(static_cast<double>(lineBuffer[icol]-minValue)/(maxValue-minValue)*nbin)];
- }
- }
- nsample=imgReader.nrOfCol()*imgReader.nrOfRow()-ninvalid;
+ maxValue=max_opt.size();
+ unsigned long int nsample=imgReader.getHistogram(output,minValue,maxValue,nbin,band_opt[0]);
std::cout.precision(10);
for(int bin=0;bin<nbin;++bin){
- nsample+=output[bin];
+ // nsample+=output[bin];
if(output[bin]>0){
std::cout << (maxValue-minValue)*bin/(nbin-1)+minValue << " ";
if(relative_opt[0])
diff --git a/src/imageclasses/ImgReaderGdal.cc b/src/imageclasses/ImgReaderGdal.cc
index f28c076..7c1991c 100644
--- a/src/imageclasses/ImgReaderGdal.cc
+++ b/src/imageclasses/ImgReaderGdal.cc
@@ -445,6 +445,45 @@ void ImgReaderGdal::getMinMax(double& minValue, double& maxValue, int band, bool
}
}
+unsigned long int ImgReaderGdal::getHistogram(vector<unsigned long int>& histvector, double& min, double& max, int& nbin, int theBand) const{
+ double minValue=0;
+ double maxValue=0;
+ getMinMax(minValue,maxValue,theBand);
+ if(min<max&&min>minValue)
+ minValue=min;
+ else
+ min=minValue;
+ if(min<max&&max<maxValue)
+ maxValue=max;
+ else
+ max=maxValue;
+ if(nbin==0)
+ nbin=maxValue-minValue+1;
+ assert(nbin>0);
+ histvector.resize(nbin);
+ unsigned long int nsample=0;
+ unsigned long int ninvalid=0;
+ std::vector<double> lineBuffer(nrOfCol());
+ for(int i=0;i<nbin;histvector[i++]=0);
+ for(int irow=0;irow<nrOfRow();++irow){
+ readData(lineBuffer,GDT_Float64,irow,theBand);
+ for(int icol=0;icol<nrOfCol();++icol){
+ if(isNoData(lineBuffer[icol]))
+ ++ninvalid;
+ else if(lineBuffer[icol]>maxValue)
+ ++ninvalid;
+ else if(lineBuffer[icol]<minValue)
+ ++ninvalid;
+ else if(lineBuffer[icol]==maxValue)
+ ++histvector[nbin-1];
+ else
+ ++histvector[static_cast<int>(static_cast<double>(lineBuffer[icol]-minValue)/(maxValue-minValue)*(nbin-1))];
+ }
+ }
+ unsigned long int nvalid=nrOfCol()*nrOfRow()-ninvalid;
+ return nvalid;
+}
+
void ImgReaderGdal::getRange(vector<short>& range, int band) const
{
vector<short> lineBuffer(nrOfCol());
diff --git a/src/imageclasses/ImgReaderGdal.h b/src/imageclasses/ImgReaderGdal.h
index f11c7e2..cb053d6 100644
--- a/src/imageclasses/ImgReaderGdal.h
+++ b/src/imageclasses/ImgReaderGdal.h
@@ -78,6 +78,7 @@ public:
void getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double& minValue, double& maxValue) const;
void getMinMax(double& minValue, double& maxValue, int band=0, bool exhaustiveSearch=false) const;
double getMin(int& col, int& row, int band=0) const;
+ unsigned long int getHistogram(vector<unsigned long int>& histvector, double& min, double& max,int& nbin, int theBand=0) const;
double getMax(int& col, int& row, int band=0) const;
void getRefPix(double& refX, double &refY, int band=0) const;
void getRange(vector<short>& range, int Band=0) const;
diff --git a/src/imageclasses/Makefile.am b/src/imageclasses/Makefile.am
index fceea0e..4af4a99 100644
--- a/src/imageclasses/Makefile.am
+++ b/src/imageclasses/Makefile.am
@@ -1,5 +1,5 @@
-AM_LDFLAGS = $(GDAL_LDFLAGS) @AM_LDFLAGS@
-AM_CXXFLAGS = -I$(top_srcdir)/src $(GDAL_CFLAGS) @AM_CXXFLAGS@
+AM_LDFLAGS = $(GSL_LDFLAGS) $(GDAL_LDFLAGS) @AM_LDFLAGS@
+AM_CXXFLAGS = -I$(top_srcdir)/src $(GSL_CFLAGS) $(GDAL_CFLAGS) @AM_CXXFLAGS@
###############################################################################
# THE LIBRARIES TO BUILD
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pktools.git
More information about the Pkg-grass-devel
mailing list