From f62ff3083e3e96d1e976f12dd9cb920ef0a3520d Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 23 Feb 2009 21:01:08 +0000 Subject: [PATCH] Landsat datasets make negative product load parameters from dataset specific file. custom sun direction datasets with single raytracing for testing with hypothetical new datasets --- geo/CMakeLists.txt | 1 + ...ProcessingData.cpp => tcCustomSunDirection.cpp} | 38 ++++++--------- geo/{tcProcessingData.h => tcCustomSunDirection.h} | 21 ++++----- geo/tcElevationOptimization.cpp | 54 ++++++++++++++------- geo/tcElevationOptimization.h | 4 +- geo/tcGlobe.cpp | 24 ++++++---- geo/tcLandsatData.cpp | 4 +- geo/tcNegativeProduct.cpp | 55 +++++++++++++--------- geo/tcNegativeProduct.h | 7 +++ geo/tcProcessingData.cpp | 10 ++-- geo/tcProcessingData.h | 4 +- geo/tcRaytracedShadowMap.cpp | 51 ++++++++++++++++++-- geo/tcRaytracedShadowMap.h | 10 ++++ geo/tcShadowClassifyingData.cpp | 2 - 14 files changed, 187 insertions(+), 98 deletions(-) copy geo/{tcProcessingData.cpp => tcCustomSunDirection.cpp} (65%) copy geo/{tcProcessingData.h => tcCustomSunDirection.h} (75%) diff --git a/geo/CMakeLists.txt b/geo/CMakeLists.txt index 97c73ad..1679504 100644 --- a/geo/CMakeLists.txt +++ b/geo/CMakeLists.txt @@ -43,6 +43,7 @@ set(tecorrec_geo_SRCS tcShadowClassifyingData.cpp tcLandsatMetaData.cpp tcLandsatData.cpp + tcCustomSunDirection.cpp tcProcessingData.cpp tcExportText.cpp ) diff --git a/geo/tcProcessingData.cpp b/geo/tcCustomSunDirection.cpp similarity index 65% copy from geo/tcProcessingData.cpp copy to geo/tcCustomSunDirection.cpp index 2b5e020..70e2097 100644 --- a/geo/tcProcessingData.cpp +++ b/geo/tcCustomSunDirection.cpp @@ -18,19 +18,15 @@ ***************************************************************************/ /** - * @file tcProcessingData.cpp - * @brief Processing data channels. + * @file tcCustomSunDirection.cpp + * @brief Dataset with raytraced shadow classification using a custom sun direction. */ -#include "tcProcessingData.h" -#include "tcLandsatData.h" +#include "tcCustomSunDirection.h" #include "tcSrtmModel.h" #include "tcChannelManager.h" #include "tcLambertianShading.h" -#include "tcElevation.h" -#include "tcElevationDifference.h" -#include "tcElevationOptimization.h" -#include "tcPixelOp.h" +#include "tcRaytracedShadowMap.h" #include @@ -39,32 +35,28 @@ */ /// Primary constructor. -tcProcessingData::tcProcessingData(const QList& landsatDatasets, tcSrtmModel* dem) -: tcGeoImageData() +tcCustomSunDirection::tcCustomSunDirection(tcSrtmModel* dem, const tcGeo& sunDirection, const tcGeo& sunReference) +: tcShadowClassifyingData() { - setName(QObject::tr("Processing channels")); + setName(QObject::tr("Custom sun direction")); //setTexToGeo(landsatDatasets[0]->texToGeo()); + setSunDirection(sunDirection, sunReference); +/* tcGeoImageData* refImagery = landsatDatasets[0]; tcChannel* reference = refImagery->channelManager()->channel(0); tcLambertianShading* upshading = new tcLambertianShading(reference, dem, this, maths::Vector<3,float>(0.0f, 0.0f, 1.0f)); channelManager()->addChannel(upshading); + */ - tcElevation* elevation = new tcElevation(refImagery, reference, dem, this); - channelManager()->addChannel(elevation); - - tcElevationDifference* elevationDifference = new tcElevationDifference(refImagery, reference, dem, this); - channelManager()->addChannel(elevationDifference); - - tcElevationOptimization* elevationOpt = new tcElevationOptimization(landsatDatasets, dem, this); - channelManager()->addChannel(elevationOpt); - - tcPixelOp* elevDiff = new tcPixelOp(tcPixelOp::Diff, QList() << elevationOpt << elevation); - channelManager()->addChannel(elevDiff); + double pixelRes = 30.0/6378.137e3; + tcRaytracedShadowMap* raytrace = new tcRaytracedShadowMap(tcGeo(pixelRes, pixelRes), dem, this); + channelManager()->addChannel(raytrace); + setShadowClassification(raytrace); } /// Destructor. -tcProcessingData::~tcProcessingData() +tcCustomSunDirection::~tcCustomSunDirection() { } diff --git a/geo/tcProcessingData.h b/geo/tcCustomSunDirection.h similarity index 75% copy from geo/tcProcessingData.h copy to geo/tcCustomSunDirection.h index b2737c1..1b3a34f 100644 --- a/geo/tcProcessingData.h +++ b/geo/tcCustomSunDirection.h @@ -17,23 +17,20 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef _tcProcessingData_h_ -#define _tcProcessingData_h_ +#ifndef _tcCustomSunDirection_h_ +#define _tcCustomSunDirection_h_ /** - * @file tcProcessingData.h - * @brief Processing data channels. + * @file tcCustomSunDirection.h + * @brief Dataset with raytraced shadow classification using a custom sun direction. */ -#include "tcGeoImageData.h" +#include "tcShadowClassifyingData.h" -#include - -class tcLandsatData; class tcSrtmModel; -/// Processing data channels. -class tcProcessingData : public tcGeoImageData +/// Dataset with raytraced shadow classification using a custom sun direction. +class tcCustomSunDirection : public tcShadowClassifyingData { public: @@ -42,10 +39,10 @@ class tcProcessingData : public tcGeoImageData */ /// Primary constructor. - tcProcessingData(const QList& landsatDatasets, tcSrtmModel* dem); + tcCustomSunDirection(tcSrtmModel* dem, const tcGeo& sunDirection, const tcGeo& sunReference); /// Destructor. - virtual ~tcProcessingData(); + virtual ~tcCustomSunDirection(); }; #endif diff --git a/geo/tcElevationOptimization.cpp b/geo/tcElevationOptimization.cpp index cf85362..bf78aac 100644 --- a/geo/tcElevationOptimization.cpp +++ b/geo/tcElevationOptimization.cpp @@ -25,7 +25,7 @@ #include "tcElevationOptimization.h" #include "tcChannelConfigWidget.h" #include "tcSrtmModel.h" -#include "tcLandsatData.h" +#include "tcShadowClassifyingData.h" #include #include @@ -43,12 +43,12 @@ */ /// Primary constructor. -tcElevationOptimization::tcElevationOptimization(const QList& landsatDatasets, tcSrtmModel* dem, tcGeoImageData* imagery) +tcElevationOptimization::tcElevationOptimization(const QList& datasets, tcSrtmModel* dem, tcGeoImageData* imagery) : tcChannelDem(dem, imagery, tr("Elevation Optimization"), tr("Optimizes elevation using image data."), false) -, m_numDatasets(landsatDatasets.size()) +, m_numDatasets(datasets.size()) , m_datasets(new tcGeoImageData*[m_numDatasets]) , m_texToDatasetTex(new tcAffineTransform2[m_numDatasets]) , m_shadowChannels(new tcChannel*[m_numDatasets]) @@ -63,13 +63,19 @@ tcElevationOptimization::tcElevationOptimization(const QList& la { for (int i = 0; i < m_numDatasets; ++i) { - tcLandsatData* landsat = landsatDatasets[i]; + tcShadowClassifyingData* landsat = datasets[i]; m_datasets[i] = landsat; m_texToDatasetTex[i] = imagery->texToGeo() * landsat->geoToTex(); m_shadowChannels[i] = landsat->shadowClassification(); - m_shadowChannels[i]->addDerivitive(this); + if (0 != m_shadowChannels[i]) + { + m_shadowChannels[i]->addDerivitive(this); + } m_shadingChannels[i] = landsat->shading(); - m_shadingChannels[i]->addDerivitive(this); + if (0 != m_shadingChannels[i]) + { + m_shadingChannels[i]->addDerivitive(this); + } m_datum[i] = 0; } } @@ -81,8 +87,14 @@ tcElevationOptimization::~tcElevationOptimization() delete [] m_texToDatasetTex; for (int i = 0; i < m_numDatasets; ++i) { - m_shadowChannels[i]->removeDerivitive(this); - m_shadingChannels[i]->removeDerivitive(this); + if (0 != m_shadowChannels[i]) + { + m_shadowChannels[i]->removeDerivitive(this); + } + if (0 != m_shadingChannels[i]) + { + m_shadingChannels[i]->removeDerivitive(this); + } delete m_datum[i]; } delete [] m_shadowChannels; @@ -267,8 +279,15 @@ tcAbstractPixelData* tcElevationOptimization::loadPortion(double x1, double y1, { return 0; } - Reference shadingData = m_shadingChannels[i]->loadPortion(xy1[0], xy1[1], xy2[0], xy2[1]); - m_shadingData[i] = dynamicCast*>(shadingData); + if (0 != m_shadingChannels[i]) + { + Reference shadingData = m_shadingChannels[i]->loadPortion(xy1[0], xy1[1], xy2[0], xy2[1]); + m_shadingData[i] = dynamicCast*>(shadingData); + } + else + { + m_shadingData[i] = 0; + } } /// @todo What if its a different size because the portion has changed? @@ -562,12 +581,15 @@ float tcElevationOptimization::cost(int x1, int y1, int x2, int y2) const ++countLitFacing; } // Simple shape from shading - float intensity = m_shadingData[ds]->sampleFloat((float)i/(width-1), (float)j/(height-1)); - // intensity = cos(theta) = L.N - maths::Vector<3,float> xTan(1.0f, 0.0f, dh_dx); - maths::Vector<3,float> yTan(0.0f, 1.0f, dh_dy); - costShading += MySqr(acos(qMin(1.0f, intensity)) - acos(qMin(1.0f, dsCache->light*maths::cross(xTan, yTan).normalized()))); - ++countShading; + if (0 != m_shadingData[ds]) + { + float intensity = m_shadingData[ds]->sampleFloat((float)i/(width-1), (float)j/(height-1)); + // intensity = cos(theta) = L.N + maths::Vector<3,float> xTan(1.0f, 0.0f, dh_dx); + maths::Vector<3,float> yTan(0.0f, 1.0f, dh_dy); + costShading += MySqr(acos(qMin(1.0f, intensity)) - acos(qMin(1.0f, dsCache->light*maths::cross(xTan, yTan).normalized()))); + ++countShading; + } } if (isShadowEntrance) { diff --git a/geo/tcElevationOptimization.h b/geo/tcElevationOptimization.h index 65b6d4a..3addce7 100644 --- a/geo/tcElevationOptimization.h +++ b/geo/tcElevationOptimization.h @@ -31,7 +31,7 @@ #include -class tcLandsatData; +class tcShadowClassifyingData; class tcGeoImageData; class QSpinBox; @@ -47,7 +47,7 @@ class tcElevationOptimization : public tcChannelDem */ /// Primary constructor. - tcElevationOptimization(const QList& landsatDatasets, tcSrtmModel* dem, tcGeoImageData* imagery); + tcElevationOptimization(const QList& datasets, tcSrtmModel* dem, tcGeoImageData* imagery); /// Destructor. virtual ~tcElevationOptimization(); diff --git a/geo/tcGlobe.cpp b/geo/tcGlobe.cpp index 9f81830..afbf819 100644 --- a/geo/tcGlobe.cpp +++ b/geo/tcGlobe.cpp @@ -26,6 +26,7 @@ #include "tcGeoImageData.h" #include "tcLandsatData.h" #include "tcProcessingData.h" +#include "tcCustomSunDirection.h" #include "tcSrtmModel.h" #include #include @@ -62,23 +63,28 @@ tcGlobe::tcGlobe(double meanRadius) m_colourMapping[i][0] = -1; m_colourMapping[i][1] = -1; } - QList landsatDatasets; - landsatDatasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282000081EDC00/", m_elevation); + QList datasets; + datasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282000081EDC00/", m_elevation); // this one is a bit rubbish, the sun is too high - //landsatDatasets << new tcLandsatData("/home/james/cs/pro/data/LE71950281999206EDC01/", m_elevation); + //datasets << new tcLandsatData("/home/james/cs/pro/data/LE71950281999206EDC01/", m_elevation); // high azimuth, low elevation - landsatDatasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282001307EDC00/", m_elevation); - landsatDatasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282002006EDC00/", m_elevation); - landsatDatasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282002310EDC00/", m_elevation); + datasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282001307EDC00/", m_elevation); + datasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282002006EDC00/", m_elevation); + datasets << new tcLandsatData("/home/james/cs/pro/data/LE71950282002310EDC00/", m_elevation); - landsatDatasets << new tcLandsatData("/home/james/cs/pro/data/etp195r28_5t19900910/", m_elevation); + datasets << new tcLandsatData("/home/james/cs/pro/data/etp195r28_5t19900910/", m_elevation); - foreach (tcLandsatData* dataset, landsatDatasets) + datasets << new tcCustomSunDirection(m_elevation+1, tcGeo(-40.0*M_PI/180, 30.0*M_PI/180), + tcGeo(7.0*M_PI/180, 46.0*M_PI/180)); + datasets << new tcCustomSunDirection(m_elevation+1, tcGeo(-20.0*M_PI/180, 30.0*M_PI/180), + tcGeo(7.0*M_PI/180, 46.0*M_PI/180)); + + foreach (tcShadowClassifyingData* dataset, datasets) { addImagery(dataset); } - addImagery(new tcProcessingData(landsatDatasets, m_elevation)); + addImagery(new tcProcessingData(datasets, m_elevation)); } /// Destructor. diff --git a/geo/tcLandsatData.cpp b/geo/tcLandsatData.cpp index 05f4152..f8a9f58 100644 --- a/geo/tcLandsatData.cpp +++ b/geo/tcLandsatData.cpp @@ -213,7 +213,7 @@ tcLandsatData::tcLandsatData(const QString& path, tcSrtmModel* dem) { mainColourChannels += channelManager()->channel(i); } - tcChannel* shadowClassification = new tcNegativeProduct(mainColourChannels); + tcNegativeProduct* shadowClassification = new tcNegativeProduct(mainColourChannels); channelManager()->addChannel(shadowClassification); setShadowClassification(shadowClassification); @@ -267,6 +267,8 @@ tcLandsatData::tcLandsatData(const QString& path, tcSrtmModel* dem) channelManager()->addChannel(sc); */ + shadowClassification->loadParams(path + "negativeproduct.npp"); + // Only load one metafile break; } diff --git a/geo/tcNegativeProduct.cpp b/geo/tcNegativeProduct.cpp index be2db60..3e51f52 100644 --- a/geo/tcNegativeProduct.cpp +++ b/geo/tcNegativeProduct.cpp @@ -191,6 +191,38 @@ tcChannelConfigWidget* tcNegativeProduct::configWidget() } /* + * Parameters + */ + +/// Load parameters. +void tcNegativeProduct::loadParams(const QString& filename) +{ + configWidget(); + m_saveParameters = filename; + + QFile file(m_saveParameters); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QMessageBox::warning(m_configWidget, + tr("Open failed."), + tr("Could not open '%1' for reading.").arg(m_saveParameters)); + return; + } + + QTextStream in(&file); + in >> m_threshold; + m_sliderThreshold->setValue(log(m_threshold)*100); + for (int i = 0; i < m_powerSliders.size(); ++i) + { + in >> m_powers[i]; + m_powerSliders[i]->setValue(m_powers[i]*10); + } + + invalidate(); + m_configWidget->requestRedraw(); +} + +/* * Interface for derived class to implement */ @@ -566,28 +598,7 @@ void tcNegativeProduct::loadParams() { return; } - m_saveParameters = saveParameters; - - QFile file(m_saveParameters); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - { - QMessageBox::warning(m_configWidget, - tr("Open failed."), - tr("Could not open '%1' for reading.").arg(m_saveParameters)); - return; - } - - QTextStream in(&file); - in >> m_threshold; - m_sliderThreshold->setValue(log(m_threshold)*100); - for (int i = 0; i < m_powerSliders.size(); ++i) - { - in >> m_powers[i]; - m_powerSliders[i]->setValue(m_powers[i]*10); - } - - invalidate(); - m_configWidget->requestRedraw(); + loadParams(saveParameters); } /* diff --git a/geo/tcNegativeProduct.h b/geo/tcNegativeProduct.h index 17668ab..e4cddf5 100644 --- a/geo/tcNegativeProduct.h +++ b/geo/tcNegativeProduct.h @@ -57,6 +57,13 @@ class tcNegativeProduct : public tcChannel // Reimplemented virtual tcChannelConfigWidget* configWidget(); + /* + * Parameters + */ + + /// Load parameters. + void loadParams(const QString& filename); + protected: /* diff --git a/geo/tcProcessingData.cpp b/geo/tcProcessingData.cpp index 2b5e020..fcc5520 100644 --- a/geo/tcProcessingData.cpp +++ b/geo/tcProcessingData.cpp @@ -23,7 +23,7 @@ */ #include "tcProcessingData.h" -#include "tcLandsatData.h" +#include "tcShadowClassifyingData.h" #include "tcSrtmModel.h" #include "tcChannelManager.h" #include "tcLambertianShading.h" @@ -39,13 +39,13 @@ */ /// Primary constructor. -tcProcessingData::tcProcessingData(const QList& landsatDatasets, tcSrtmModel* dem) +tcProcessingData::tcProcessingData(const QList& datasets, tcSrtmModel* dem) : tcGeoImageData() { setName(QObject::tr("Processing channels")); - //setTexToGeo(landsatDatasets[0]->texToGeo()); + //setTexToGeo(datasets[0]->texToGeo()); - tcGeoImageData* refImagery = landsatDatasets[0]; + tcGeoImageData* refImagery = datasets[0]; tcChannel* reference = refImagery->channelManager()->channel(0); tcLambertianShading* upshading = new tcLambertianShading(reference, dem, this, maths::Vector<3,float>(0.0f, 0.0f, 1.0f)); @@ -57,7 +57,7 @@ tcProcessingData::tcProcessingData(const QList& landsatDatasets, tcElevationDifference* elevationDifference = new tcElevationDifference(refImagery, reference, dem, this); channelManager()->addChannel(elevationDifference); - tcElevationOptimization* elevationOpt = new tcElevationOptimization(landsatDatasets, dem, this); + tcElevationOptimization* elevationOpt = new tcElevationOptimization(datasets, dem, this); channelManager()->addChannel(elevationOpt); tcPixelOp* elevDiff = new tcPixelOp(tcPixelOp::Diff, QList() << elevationOpt << elevation); diff --git a/geo/tcProcessingData.h b/geo/tcProcessingData.h index b2737c1..7a020fb 100644 --- a/geo/tcProcessingData.h +++ b/geo/tcProcessingData.h @@ -29,7 +29,7 @@ #include -class tcLandsatData; +class tcShadowClassifyingData; class tcSrtmModel; /// Processing data channels. @@ -42,7 +42,7 @@ class tcProcessingData : public tcGeoImageData */ /// Primary constructor. - tcProcessingData(const QList& landsatDatasets, tcSrtmModel* dem); + tcProcessingData(const QList& datasets, tcSrtmModel* dem); /// Destructor. virtual ~tcProcessingData(); diff --git a/geo/tcRaytracedShadowMap.cpp b/geo/tcRaytracedShadowMap.cpp index e6310d0..a636e49 100644 --- a/geo/tcRaytracedShadowMap.cpp +++ b/geo/tcRaytracedShadowMap.cpp @@ -23,6 +23,7 @@ */ #include "tcRaytracedShadowMap.h" +#include "tcGeoImageData.h" #include @@ -36,6 +37,19 @@ tcRaytracedShadowMap::tcRaytracedShadowMap(tcChannel* reference, tcSrtmModel* de tr("Raytraced Shadow Map"), tr("Uses ray tracing and elevation data to highlight shadows.")) , m_referenceChannel(reference) +, m_resolution() +, m_texToGeo(imagery->texToGeo()) +{ +} + +/// Primary constructor. +tcRaytracedShadowMap::tcRaytracedShadowMap(const tcGeo& resolution, tcSrtmModel* dem, tcGeoImageData* imagery) +: tcChannelDem(dem, imagery, + tr("Raytraced Shadow Map"), + tr("Uses ray tracing and elevation data to highlight shadows.")) +, m_referenceChannel(0) +, m_resolution(resolution) +, m_texToGeo(imagery->texToGeo()) { } @@ -50,14 +64,43 @@ tcRaytracedShadowMap::~tcRaytracedShadowMap() void tcRaytracedShadowMap::roundPortion(double* x1, double* y1, double* x2, double* y2) { - m_referenceChannel->roundPortion(x1,y1,x2,y2); + //m_referenceChannel->roundPortion(x1,y1,x2,y2); } tcAbstractPixelData* tcRaytracedShadowMap::loadPortion(double x1, double y1, double x2, double y2) { - Reference channelData = m_referenceChannel->loadPortion(x1, y1, x2, y2); - int width = channelData->width(); - int height = channelData->height(); + int width; + int height; + if (0 != m_referenceChannel) + { + Reference channelData = m_referenceChannel->loadPortion(x1, y1, x2, y2); + width = channelData->width(); + height = channelData->height(); + } + else + { + tcGeo diag = (tcGeo)(m_texToGeo * maths::Vector<2,double>(x1, y1) - m_texToGeo * maths::Vector<2,double>(x2,y2)); + maths::Vector<2,double> res = diag / m_resolution; + width = abs((int)res[0]); + height = abs((int)res[1]); + // ensure resw and resh are powers of 2 + for (int i = 1; i < 20; ++i) + { + if (0 == (width & ~((1<* data = new tcPixelData(width, height); diff --git a/geo/tcRaytracedShadowMap.h b/geo/tcRaytracedShadowMap.h index 64890d8..b193f1e 100644 --- a/geo/tcRaytracedShadowMap.h +++ b/geo/tcRaytracedShadowMap.h @@ -26,6 +26,7 @@ */ #include "tcChannelDem.h" +#include "tcAffineTransform.h" /// Shadow map using ray tracing of DEM. class tcRaytracedShadowMap : public tcChannelDem @@ -39,6 +40,9 @@ class tcRaytracedShadowMap : public tcChannelDem /// Primary constructor. tcRaytracedShadowMap(tcChannel* reference, tcSrtmModel* dem, tcGeoImageData* imagery); + /// Primary constructor. + tcRaytracedShadowMap(const tcGeo& resolution, tcSrtmModel* dem, tcGeoImageData* imagery); + /// Destructor. virtual ~tcRaytracedShadowMap(); @@ -62,6 +66,12 @@ class tcRaytracedShadowMap : public tcChannelDem /// We'll use the same resolution as this reference channel. tcChannel* m_referenceChannel; + + /// Resolution if no reference channel is provided. + tcGeo m_resolution; + + /// Texture to geographical coordinate transform. + tcAffineTransform2 m_texToGeo; }; #endif diff --git a/geo/tcShadowClassifyingData.cpp b/geo/tcShadowClassifyingData.cpp index 9a22878..b8cc9bb 100644 --- a/geo/tcShadowClassifyingData.cpp +++ b/geo/tcShadowClassifyingData.cpp @@ -40,8 +40,6 @@ tcShadowClassifyingData::tcShadowClassifyingData() /// Destructor. tcShadowClassifyingData::~tcShadowClassifyingData() { - delete m_shadowClassification; - delete m_shading; } /* -- 2.11.4.GIT