From 475468319c37491078758425af3bb8e7d438074c Mon Sep 17 00:00:00 2001 From: James Hogan Date: Sun, 30 Nov 2008 02:01:35 +0000 Subject: [PATCH] Basic processing channels and channel groups including infrastructure for shadow free chromaticities --- geo/CMakeLists.txt | 7 +- geo/tcChannel.cpp | 13 +- geo/tcChannel.h | 9 +- geo/tcChannelChromaticity.cpp | 75 +++++++ ...{tcChannelManager.h => tcChannelChromaticity.h} | 48 +++-- ...hannelManager.cpp => tcChannelConfigWidget.cpp} | 40 +--- tcMainWindow.h => geo/tcChannelConfigWidget.h | 42 ++-- geo/tcChannelGroup.cpp | 216 +++++++++++++++++++++ geo/{tcChannel.h => tcChannelGroup.h} | 61 ++++-- geo/tcChannelManager.cpp | 11 +- geo/tcChannelManager.h | 5 +- geo/tcLandsatData.cpp | 13 ++ geo/tcShadowFreeChromaticities.cpp | 131 +++++++++++++ ...annelManager.h => tcShadowFreeChromaticities.h} | 48 +++-- tcColourMapWidget.cpp | 15 +- tcColourMapWidget.h | 8 +- tcMainWindow.cpp | 16 ++ tcMainWindow.h | 9 + 18 files changed, 629 insertions(+), 138 deletions(-) create mode 100644 geo/tcChannelChromaticity.cpp copy geo/{tcChannelManager.h => tcChannelChromaticity.h} (63%) copy geo/{tcChannelManager.cpp => tcChannelConfigWidget.cpp} (69%) copy tcMainWindow.h => geo/tcChannelConfigWidget.h (73%) create mode 100644 geo/tcChannelGroup.cpp copy geo/{tcChannel.h => tcChannelGroup.h} (68%) create mode 100644 geo/tcShadowFreeChromaticities.cpp copy geo/{tcChannelManager.h => tcShadowFreeChromaticities.h} (60%) diff --git a/geo/CMakeLists.txt b/geo/CMakeLists.txt index bb774a7..22ad3c3 100644 --- a/geo/CMakeLists.txt +++ b/geo/CMakeLists.txt @@ -16,8 +16,12 @@ set(tecorrec_geo_SRCS tcSrtmData.cpp tcPixelData.cpp tcChannel.cpp - tcChannelFile.cpp + tcChannelGroup.cpp tcChannelManager.cpp + tcChannelConfigWidget.cpp + tcChannelFile.cpp + tcChannelChromaticity.cpp + tcShadowFreeChromaticities.cpp tcGeoImageData.cpp tcSensor.cpp tcSpectrum.cpp @@ -27,6 +31,7 @@ set(tecorrec_geo_SRCS ) set(tecorrec_geo_HEADERS + tcChannelConfigWidget.h ) qt4_wrap_cpp(tecorrec_geo_MOCS ${tecorrec_geo_HEADERS}) diff --git a/geo/tcChannel.cpp b/geo/tcChannel.cpp index da9c2e2..54acfda 100644 --- a/geo/tcChannel.cpp +++ b/geo/tcChannel.cpp @@ -72,10 +72,21 @@ void tcChannel::setDescription(const QString& description) * Main image interface */ +/// Get configuration widget. +tcChannelConfigWidget* tcChannel::configWidget() +{ + return 0; +} + +/// Get GL texture ID of thumbnail of the channel. +GLuint tcChannel::thumbnailTexture() +{ + return 0; +} + /// Get a reference to the pixel data of a portion of the image. Reference tcChannel::portion(double* x1, double* y1, double* x2, double* y2) { - int stackProtection = 12345; // If the portion is out of date, remove it roundPortion(x1,y1,x2,y2); if (0 != m_portion) diff --git a/geo/tcChannel.h b/geo/tcChannel.h index 0b76599..7485e05 100644 --- a/geo/tcChannel.h +++ b/geo/tcChannel.h @@ -31,6 +31,8 @@ #include +class tcChannelConfigWidget; + /// A single abstract image channel. class tcChannel { @@ -66,8 +68,11 @@ class tcChannel * Main image interface */ + /// Get configuration widget. + virtual tcChannelConfigWidget* configWidget(); + /// Get GL texture ID of thumbnail of the channel. - virtual GLuint thumbnailTexture() = 0; + virtual GLuint thumbnailTexture(); /// Get a reference to the pixel data of a portion of the image. Reference portion(double* x1, double* y1, double* x2, double* y2); @@ -75,7 +80,7 @@ class tcChannel /// Get GL texture ID of portion of the channel. GLuint portionTexture(double* x1, double* y1, double* x2, double* y2); - protected: + //protected: /* * Interface for derived class to implement diff --git a/geo/tcChannelChromaticity.cpp b/geo/tcChannelChromaticity.cpp new file mode 100644 index 0000000..cef50fe --- /dev/null +++ b/geo/tcChannelChromaticity.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * This file is part of Tecorrec. * + * Copyright 2008 James Hogan * + * * + * Tecorrec is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * Tecorrec is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with Tecorrec. If not, write to the Free Software Foundation, * + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +/** + * @file tcChannelChromaticity.cpp + * @brief An image processing channel of the chromaticity between two channels. + */ + +#include "tcChannelChromaticity.h" + +#include + +/* + * Constructors + destructor + */ + +/// Primary constructor. +tcChannelChromaticity::tcChannelChromaticity(tcChannel* numerator, tcChannel* denominator) +: tcChannel(QObject::tr("Chromaticity(%1,%2)").arg(numerator->name()).arg(denominator->name()), + QObject::tr("Chromaticity (division) of the %1 and %2 channels").arg(numerator->name()).arg(denominator->name())) +, m_numerator(numerator) +, m_denominator(denominator) +{ +} + +/// Destructor. +tcChannelChromaticity::~tcChannelChromaticity() +{ +} + +/* + * Interface for derived class to implement + */ + +void tcChannelChromaticity::roundPortion(double* x1, double* y1, double* x2, double* y2) +{ + m_numerator->roundPortion(x1, y1, x2, y2); +} + +tcAbstractPixelData* tcChannelChromaticity::loadPortion(double x1, double y1, double x2, double y2) +{ + Reference > numerator = dynamic_cast*>(m_numerator->loadPortion(x1, y1, x2, y2)); + Reference > denominator = dynamic_cast*>(m_denominator->loadPortion(x1, y1, x2, y2)); + + tcPixelData* data = 0; + if (0 != numerator && 0 != denominator) + { + int width = numerator->width(); + int height = numerator->height(); + Q_ASSERT(width == denominator->width()); + Q_ASSERT(height == denominator->height()); + data = new tcPixelData(width, height); + for (int i = 0; i < width*height; ++i) + { + data->buffer()[i] = (double)numerator->buffer()[i] / denominator->buffer()[i]; + } + } + return data; +} diff --git a/geo/tcChannelManager.h b/geo/tcChannelChromaticity.h similarity index 63% copy from geo/tcChannelManager.h copy to geo/tcChannelChromaticity.h index b0bd8b4..5bb8ade 100644 --- a/geo/tcChannelManager.h +++ b/geo/tcChannelChromaticity.h @@ -17,20 +17,20 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef _tcChannelManager_h_ -#define _tcChannelManager_h_ +#ifndef _tcChannelChromaticity_h_ +#define _tcChannelChromaticity_h_ /** - * @file tcChannelManager.h - * @brief Manages a set of channels, any of which can be mapped to RGB. + * @file tcChannelChromaticity.h + * @brief An image processing channel of the chromaticity between two channels. */ -#include +#include "tcChannel.h" -class tcChannel; +class tcChannelConfigWidget; -/// Manages a set of channels, any of which can be mapped to RGB. -class tcChannelManager +/// An image processing channel of the chromaticity between two channels. +class tcChannelChromaticity : public tcChannel { public: @@ -38,28 +38,23 @@ class tcChannelManager * Constructors + destructor */ - /// Default constructor. - tcChannelManager(); + /// Primary constructor. + tcChannelChromaticity(tcChannel* numerator, tcChannel* denominator); /// Destructor. - virtual ~tcChannelManager(); + virtual ~tcChannelChromaticity(); - /* - * Accessors - */ - - /// Get the number of channel. - int numChannels() const; - - /// Get a specific channel. - tcChannel* channel(int index) const; + protected: /* - * Channel operations + * Interface for derived class to implement */ - /// Add and take ownership of a channel. - void addChannel(tcChannel* channel); + // Reimplemented + virtual void roundPortion(double* x1, double* y1, double* x2, double* y2); + + // Reimplemented + virtual tcAbstractPixelData* loadPortion(double x1, double y1, double x2, double y2); private: @@ -67,8 +62,11 @@ class tcChannelManager * Variables */ - /// List of channels. - QList m_channels; + /// Numerator channel. + tcChannel* m_numerator; + + /// Denominator channel. + tcChannel* m_denominator; }; #endif diff --git a/geo/tcChannelManager.cpp b/geo/tcChannelConfigWidget.cpp similarity index 69% copy from geo/tcChannelManager.cpp copy to geo/tcChannelConfigWidget.cpp index 940d1f2..2af329a 100644 --- a/geo/tcChannelManager.cpp +++ b/geo/tcChannelConfigWidget.cpp @@ -18,49 +18,23 @@ ***************************************************************************/ /** - * @file tcChannelManager.cpp - * @brief Manages a set of channels, any of which can be mapped to RGB. + * @file tcChannelConfigWidget.cpp + * @brief A channel configuration widget. */ -#include "tcChannelManager.h" +#include "tcChannelConfigWidget.h" /* * Constructors + destructor */ -/// Default constructor. -tcChannelManager::tcChannelManager() -: m_channels() +/// Primary constructor. +tcChannelConfigWidget::tcChannelConfigWidget() +: QWidget() { } /// Destructor. -tcChannelManager::~tcChannelManager() +tcChannelConfigWidget::~tcChannelConfigWidget() { } - -/* - * Accessors - */ - -/// Get the number of channel. -int tcChannelManager::numChannels() const -{ - return m_channels.size(); -} - -/// Get a specific channel. -tcChannel* tcChannelManager::channel(int index) const -{ - return m_channels[index]; -} - -/* - * Channel operations - */ - -/// Add and take ownership of a channel. -void tcChannelManager::addChannel(tcChannel* channel) -{ - m_channels << channel; -} diff --git a/tcMainWindow.h b/geo/tcChannelConfigWidget.h similarity index 73% copy from tcMainWindow.h copy to geo/tcChannelConfigWidget.h index 804f6d2..1b13428 100644 --- a/tcMainWindow.h +++ b/geo/tcChannelConfigWidget.h @@ -17,22 +17,18 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef _tcMainWindow_h_ -#define _tcMainWindow_h_ +#ifndef _tcChannelConfigWidget_h_ +#define _tcChannelConfigWidget_h_ /** - * @file tcMainWindow.h - * @brief Main application window. + * @file tcChannelConfigWidget.h + * @brief A channel configuration widget. */ -#include +#include -class tcViewportWidget; -class tcColourMapWidget; -class tcGlobe; - -/// Main application window. -class tcMainWindow : public QMainWindow +/// A channel configuration widget. +class tcChannelConfigWidget : public QWidget { Q_OBJECT @@ -42,31 +38,21 @@ class tcMainWindow : public QMainWindow * Constructors + destructor */ - /// Default constructor. - tcMainWindow(); + /// Primary constructor. + tcChannelConfigWidget(); /// Destructor. - virtual ~tcMainWindow(); + virtual ~tcChannelConfigWidget(); - private: + signals: /* - * Widgets + * Signals */ - /// Main viewport. - tcViewportWidget* m_viewport; - - /// Colour mapper. - tcColourMapWidget* m_colourMap; - - /* - * Objects - */ + /// Emitted when settings have been changed and the viewport may need redrawing. + void updated(); - /// Globe object. - tcGlobe* m_globe; }; #endif - diff --git a/geo/tcChannelGroup.cpp b/geo/tcChannelGroup.cpp new file mode 100644 index 0000000..dd133d2 --- /dev/null +++ b/geo/tcChannelGroup.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * This file is part of Tecorrec. * + * Copyright 2008 James Hogan * + * * + * Tecorrec is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * Tecorrec is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with Tecorrec. If not, write to the Free Software Foundation, * + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +/** + * @file tcChannelGroup.cpp + * @brief A group of linked channels. + */ + +#include "tcChannelGroup.h" +#include "tcChannel.h" + +/// Our custom channel group member class. +class tcChannelGroup::Channel : public tcChannel +{ + public: + + /* + * Constructors + destructor + */ + + /// Primary constructor. + Channel(tcChannelGroup* group, int index) + : tcChannel(QString(), QString()) + , m_group(group) + , m_index(index) + { + } + + /// Destructor + virtual ~Channel() + { + } + + protected: + + /* + * Interface for derived class to implement + */ + + // Reimplemented + virtual tcChannelConfigWidget* configWidget() + { + return m_group->configWidget(); + } + + // Reimplemented + virtual void roundPortion(double* x1, double* y1, double* x2, double* y2) + { + m_group->roundPortion(x1, y1, x2, y2); + } + + // Reimplemented + virtual tcAbstractPixelData* loadPortion(double x1, double y1, double x2, double y2) + { + return m_group->portion(m_index, x1, y1, x2, y2); + } + + private: + + /* + * Variables + */ + + /// Group of channels. + tcChannelGroup* m_group; + + /// Index of this channel in m_group. + int m_index; +}; + +/* + * Constructors + destructor + */ + +/// Primary constructor. +tcChannelGroup::tcChannelGroup(int channels, const QString& name, const QString& description) +: m_name(name) +, m_description(description) +{ + for (int i = 0; i < channels; ++i) + { + Channel* channel = new Channel(this, i); + m_channels << channel; + } +} + +/// Destructor. +tcChannelGroup::~tcChannelGroup() +{ + foreach (tcChannel* channel, m_channels) + { + delete channel; + } +} + +/* + * Metadata + */ + +/// Get the channel name. +const QString& tcChannelGroup::name() const +{ + return m_name; +} + +/// Get the channel description; +const QString& tcChannelGroup::description() const +{ + return m_description; +} + +/// Set the channel name. +void tcChannelGroup::setName(const QString& name) +{ + m_name = name; +} + +/// Set the channel description. +void tcChannelGroup::setDescription(const QString& description) +{ + m_description = description; +} + +/* + * Main image interface + */ + +/// Get the list of output channels. +const QList& tcChannelGroup::channels() const +{ + return m_channels; +} + +/// Get configuration widget. +tcChannelConfigWidget* tcChannelGroup::configWidget() +{ + return 0; +} + +/// Get a reference to the pixel data of a portion of one of the output channels. +Reference tcChannelGroup::portion(int channel, double x1, double y1, double x2, double y2) +{ + // If the portion is out of date, remove it + if (0 == m_portions.size()) + { + if (m_portionPosition[0][0] != x1 || + m_portionPosition[0][1] != y1 || + m_portionPosition[1][0] != x2 || + m_portionPosition[1][1] != y2) + { + m_portions.clear(); + } + } + m_portionPosition[0][0] = x1; + m_portionPosition[0][1] = y1; + m_portionPosition[1][0] = x2; + m_portionPosition[1][1] = y2; + // Create the new portions + if (0 == m_portions.size()) + { + loadPortions(x1,y1,x2,y2); + } + // Return just the requested channel + if (channel >= 0 && channel < m_portions.size()) + { + return m_portions[channel]; + } + else + { + return 0; + } +} + +/* + * Interface for derived class to implement + */ + +/// Round coordinates to sensible values. +void tcChannelGroup::roundPortion(double* x1, double* y1, double* x2, double* y2) +{ +} + +/// Load portions of pixel data for each output channel. +void tcChannelGroup::loadPortions(double x1, double y1, double x2, double y2) +{ +} + +/* + * Interface for derived classes + */ + +/// Invalidate this channel. +void tcChannelGroup::invalidate() +{ +} + +/// Revalidate the channel, indicating that the data has changed. +void tcChannelGroup::revalidate() +{ +} diff --git a/geo/tcChannel.h b/geo/tcChannelGroup.h similarity index 68% copy from geo/tcChannel.h copy to geo/tcChannelGroup.h index 0b76599..90ded58 100644 --- a/geo/tcChannel.h +++ b/geo/tcChannelGroup.h @@ -17,34 +17,46 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef _tcChannel_h_ -#define _tcChannel_h_ +#ifndef _tcChannelGroup_h_ +#define _tcChannelGroup_h_ /** - * @file tcChannel.h - * @brief A single abstract image channel. + * @file tcChannelGroup.h + * @brief A group of linked channels. */ +#include "CountedReference.h" #include "tcPixelData.h" #include +#include -#include +class tcChannel; +class tcChannelConfigWidget; -/// A single abstract image channel. -class tcChannel +/** A single abstract image channel. + * This sort of acts as a data source for a set of related output channels. + */ +class tcChannelGroup { public: /* + * Types + */ + + /// Our custom channel group member class. + class Channel; + + /* * Constructors + destructor */ /// Primary constructor. - tcChannel(const QString& name, const QString& description); + tcChannelGroup(int channels, const QString& name, const QString& description); /// Destructor. - virtual ~tcChannel(); + virtual ~tcChannelGroup(); /* * Metadata @@ -66,16 +78,16 @@ class tcChannel * Main image interface */ - /// Get GL texture ID of thumbnail of the channel. - virtual GLuint thumbnailTexture() = 0; + /// Get the list of output channels. + const QList& channels() const; - /// Get a reference to the pixel data of a portion of the image. - Reference portion(double* x1, double* y1, double* x2, double* y2); + /// Get configuration widget. + virtual tcChannelConfigWidget* configWidget(); - /// Get GL texture ID of portion of the channel. - GLuint portionTexture(double* x1, double* y1, double* x2, double* y2); + /// Get a reference to the pixel data of a portion of one of the output channels. + Reference portion(int channel, double x1, double y1, double x2, double y2); - protected: + //protected: /* * Interface for derived class to implement @@ -84,8 +96,8 @@ class tcChannel /// Round coordinates to sensible values. virtual void roundPortion(double* x1, double* y1, double* x2, double* y2) = 0; - /// Load a portion of pixel data from the channel source, wherever that may be. - virtual tcAbstractPixelData* loadPortion(double x1, double y1, double x2, double y2) = 0; + /// Load portions of pixel data for each output channel. + virtual void loadPortions(double x1, double y1, double x2, double y2) = 0; /* * Interface for derived classes @@ -101,6 +113,15 @@ class tcChannel */ void revalidate(); + protected: + + /* + * Protected variables + */ + + /// Pixel data of a portion of each channel. + QList< Reference > m_portions; + private: /* @@ -113,8 +134,8 @@ class tcChannel /// Description of the channel. QString m_description; - /// Pixel data of a portion of the channel. - Reference m_portion; + /// Output channels. + QList m_channels; /// Portion coordinates. double m_portionPosition[2][2]; diff --git a/geo/tcChannelManager.cpp b/geo/tcChannelManager.cpp index 940d1f2..d72ba88 100644 --- a/geo/tcChannelManager.cpp +++ b/geo/tcChannelManager.cpp @@ -60,7 +60,14 @@ tcChannel* tcChannelManager::channel(int index) const */ /// Add and take ownership of a channel. -void tcChannelManager::addChannel(tcChannel* channel) +int tcChannelManager::addChannel(tcChannel* channel) { - m_channels << channel; + m_channels += channel; + return m_channels.size()-1; +} + +/// Add and take ownership of a set of channels. +void tcChannelManager::addChannels(const QList& channels) +{ + m_channels += channels; } diff --git a/geo/tcChannelManager.h b/geo/tcChannelManager.h index b0bd8b4..74928c0 100644 --- a/geo/tcChannelManager.h +++ b/geo/tcChannelManager.h @@ -59,7 +59,10 @@ class tcChannelManager */ /// Add and take ownership of a channel. - void addChannel(tcChannel* channel); + int addChannel(tcChannel* channel); + + /// Add and take ownership of a set of channels. + void addChannels(const QList& channels); private: diff --git a/geo/tcLandsatData.cpp b/geo/tcLandsatData.cpp index 07d8d51..e560d0e 100644 --- a/geo/tcLandsatData.cpp +++ b/geo/tcLandsatData.cpp @@ -26,6 +26,8 @@ #include "tcLandsatMetaData.h" #include "tcChannelManager.h" #include "tcChannelFile.h" +#include "tcChannelChromaticity.h" +#include "tcShadowFreeChromaticities.h" #include #include @@ -116,6 +118,17 @@ tcLandsatData::tcLandsatData(const QString& path) last = code; } + QList chromaticities; + chromaticities += new tcChannelChromaticity(channelManager()->channel(0), channelManager()->channel(3)); + chromaticities += new tcChannelChromaticity(channelManager()->channel(1), channelManager()->channel(3)); + chromaticities += new tcChannelChromaticity(channelManager()->channel(2), channelManager()->channel(3)); + foreach (tcChannel* channel, chromaticities) + { + channelManager()->addChannel(channel); + } + tcShadowFreeChromaticities* sfc = new tcShadowFreeChromaticities(chromaticities); + channelManager()->addChannels(sfc->channels()); + // Only load one metafile break; } diff --git a/geo/tcShadowFreeChromaticities.cpp b/geo/tcShadowFreeChromaticities.cpp new file mode 100644 index 0000000..c368261 --- /dev/null +++ b/geo/tcShadowFreeChromaticities.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * This file is part of Tecorrec. * + * Copyright 2008 James Hogan * + * * + * Tecorrec is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * Tecorrec is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with Tecorrec. If not, write to the Free Software Foundation, * + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +/** + * @file tcShadowFreeChromaticities.cpp + * @brief Remove the shadows from a set of chromaticities. + */ + +#include "tcShadowFreeChromaticities.h" +#include "tcChannelConfigWidget.h" +#include "tcChannel.h" + +#include + +/* + * Constructors + destructor + */ + +/// Primary constructor. +tcShadowFreeChromaticities::tcShadowFreeChromaticities(const QList& chromaticities) +: tcChannelGroup(chromaticities.size(), QObject::tr("Shadow free chromaticities"), QObject::tr("Re-chromatised illuminant invariant")) +, m_chromaticities(chromaticities) +, m_illuminantDirection() +, m_configWidget(0) +{ + for (int i = 0; i < chromaticities.size(); ++i) + { + channels()[i]->setName(QObject::tr("sfc(%1)").arg(chromaticities[i]->name())); + channels()[i]->setDescription(QObject::tr("Shadow-free chromaticity of %1").arg(chromaticities[i]->name())); + } +} + +/// Destructor. +tcShadowFreeChromaticities::~tcShadowFreeChromaticities() +{ + delete m_configWidget; +} + +/* + * Main image interface + */ + +tcChannelConfigWidget* tcShadowFreeChromaticities::configWidget() +{ + if (0 == m_configWidget) + { + m_configWidget = new tcChannelConfigWidget(); + m_configWidget->setWindowTitle(QObject::tr("%1 Configuration").arg(name())); + } + return m_configWidget; +} + +/* + * Interface for derived class to implement + */ + +void tcShadowFreeChromaticities::roundPortion(double* x1, double* y1, double* x2, double* y2) +{ + if (!m_chromaticities.empty()) + { + m_chromaticities[0]->roundPortion(x1,y1,x2,y2); + } +} + +void tcShadowFreeChromaticities::loadPortions(double x1, double y1, double x2, double y2) +{ + QList< Reference< tcPixelData > > chromaticityData; + QList< Reference< tcPixelData > > newChromaticityData; + int width = 0; + int height = 0; + foreach (tcChannel* channel, m_chromaticities) + { + /// @todo Make this neater + double x1a = x1; + double y1a = y1; + double x2a = x2; + double y2a = y2; + Reference< tcPixelData > pixelData = dynamicCast< tcPixelData* >(channel->portion(&x1a,&y1a,&x2a,&y2a)); + chromaticityData += pixelData; + Q_ASSERT(0 != pixelData); + // Ensure each channel is the same resolution + if (0 == width) + { + width = pixelData->width(); + } + else + { + Q_ASSERT(width == pixelData->width()); + } + if (0 == height) + { + height = pixelData->height(); + } + else + { + Q_ASSERT(height == pixelData->height()); + } + Reference< tcPixelData > newPixelData = new tcPixelData(width, height); + newChromaticityData += newPixelData; + m_portions += newPixelData; + } + + // Go through the pixels + for (int i = 0; i < width*height; ++i) + { + // Find the dot of the chromaticity values with the illuminant direction vector + // Subtract this * illuminant direction vector from original value to cancel out + + // Copy the data for now + for (int channel = 0; channel < m_chromaticities.size(); ++channel) + { + newChromaticityData[channel]->buffer()[i] = chromaticityData[channel]->buffer()[i]; + } + } +} diff --git a/geo/tcChannelManager.h b/geo/tcShadowFreeChromaticities.h similarity index 60% copy from geo/tcChannelManager.h copy to geo/tcShadowFreeChromaticities.h index b0bd8b4..7a8d44c 100644 --- a/geo/tcChannelManager.h +++ b/geo/tcShadowFreeChromaticities.h @@ -17,20 +17,22 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef _tcChannelManager_h_ -#define _tcChannelManager_h_ +#ifndef _tcShadowFreeChromaticities_h_ +#define _tcShadowFreeChromaticities_h_ /** - * @file tcChannelManager.h - * @brief Manages a set of channels, any of which can be mapped to RGB. + * @file tcShadowFreeChromaticities.h + * @brief Remove the shadows from a set of chromaticities. */ +#include "tcChannelGroup.h" + #include class tcChannel; -/// Manages a set of channels, any of which can be mapped to RGB. -class tcChannelManager +/// Remove the shadows from a set of chromaticities. +class tcShadowFreeChromaticities : public tcChannelGroup { public: @@ -38,28 +40,30 @@ class tcChannelManager * Constructors + destructor */ - /// Default constructor. - tcChannelManager(); + /// Primary constructor. + tcShadowFreeChromaticities(const QList& chromaticities); /// Destructor. - virtual ~tcChannelManager(); + virtual ~tcShadowFreeChromaticities(); /* - * Accessors + * Main image interface */ - /// Get the number of channel. - int numChannels() const; + // Reimplemented + virtual tcChannelConfigWidget* configWidget(); - /// Get a specific channel. - tcChannel* channel(int index) const; + protected: /* - * Channel operations + * Interface for derived class to implement */ - /// Add and take ownership of a channel. - void addChannel(tcChannel* channel); + // Reimplemented + virtual void roundPortion(double* x1, double* y1, double* x2, double* y2); + + // Reimplemented + virtual void loadPortions(double x1, double y1, double x2, double y2); private: @@ -67,8 +71,14 @@ class tcChannelManager * Variables */ - /// List of channels. - QList m_channels; + /// Input chromaticities. + QList m_chromaticities; + + /// Current log chromaticity illuminant direction. + QList m_illuminantDirection; + + /// Configuration widget. + tcChannelConfigWidget* m_configWidget; }; #endif diff --git a/tcColourMapWidget.cpp b/tcColourMapWidget.cpp index 202d2bf..ea521d8 100644 --- a/tcColourMapWidget.cpp +++ b/tcColourMapWidget.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include /* @@ -38,7 +39,8 @@ tcColourMapWidget::tcColourMapWidget(const QStringList& outputBands, QWidget* parent) : QScrollArea(parent) , m_layout(0) -, m_signalMapper(new QSignalMapper(this)) +, m_inputSignalMapper(new QSignalMapper(this)) +, m_groupSignalMapper(new QSignalMapper(this)) , m_outputBandButtonGroups() , m_numInputBands(0) { @@ -50,13 +52,14 @@ tcColourMapWidget::tcColourMapWidget(const QStringList& outputBands, QWidget* pa foreach (QString band, outputBands) { QButtonGroup* buttonGroup = new QButtonGroup(this); - connect(buttonGroup, SIGNAL(buttonClicked(int)), m_signalMapper, SLOT(map())); - m_signalMapper->setMapping(buttonGroup, m_outputBandButtonGroups.size()); + connect(buttonGroup, SIGNAL(buttonClicked(int)), m_groupSignalMapper, SLOT(map())); + m_groupSignalMapper->setMapping(buttonGroup, m_outputBandButtonGroups.size()); m_outputBandButtonGroups << buttonGroup; m_layout->addWidget(new QLabel(band, this), 0, m_outputBandButtonGroups.size(), Qt::AlignHCenter); } - connect(m_signalMapper, SIGNAL(mapped(int)), this, SLOT(inputBandChangedSlot(int))); + connect(m_groupSignalMapper, SIGNAL(mapped(int)), this, SLOT(inputBandChangedSlot(int))); + connect(m_inputSignalMapper, SIGNAL(mapped(int)), this, SIGNAL(inputBandClicked(int))); } /// Destructor. @@ -77,9 +80,11 @@ void tcColourMapWidget::clearInputBands() void tcColourMapWidget::addInputBand(const QString& name, const QString& description) { ++m_numInputBands; - QLabel* mainLabel = new QLabel(name, this); + QPushButton* mainLabel = new QPushButton(name, this); mainLabel->setToolTip(description); m_layout->addWidget(mainLabel, m_numInputBands, 0); + connect(mainLabel, SIGNAL(clicked()), m_inputSignalMapper, SLOT(map())); + m_inputSignalMapper->setMapping(mainLabel, m_numInputBands-1); for (int i = 0; i < m_outputBandButtonGroups.size(); ++i) { QRadioButton* radio = new QRadioButton(this); diff --git a/tcColourMapWidget.h b/tcColourMapWidget.h index e63c872..0a55cd8 100644 --- a/tcColourMapWidget.h +++ b/tcColourMapWidget.h @@ -81,6 +81,9 @@ class tcColourMapWidget : public QScrollArea * Signals */ + /// Emitted when an input band is clicked. + void inputBandClicked(int input); + /// Emitted when the input band assigned to an output is changed. void inputBandChanged(int output, int input); @@ -102,8 +105,11 @@ class tcColourMapWidget : public QScrollArea /// Main layout of the widget. QGridLayout* m_layout; + /// Input label signal mapper. + QSignalMapper* m_inputSignalMapper; + /// Group signal mapper. - QSignalMapper* m_signalMapper; + QSignalMapper* m_groupSignalMapper; /* * Variables diff --git a/tcMainWindow.cpp b/tcMainWindow.cpp index a31831d..463d612 100644 --- a/tcMainWindow.cpp +++ b/tcMainWindow.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -158,6 +159,7 @@ tcMainWindow::tcMainWindow() { m_colourMap->setInputBand(i, 2-i); } + connect(m_colourMap, SIGNAL(inputBandClicked(int)), this, SLOT(configureChannel(int))); connect(m_colourMap, SIGNAL(inputBandChanged(int, int)), m_viewport, SLOT(setColourMapping(int,int))); } @@ -180,3 +182,17 @@ tcMainWindow::~tcMainWindow() delete m_globe; } +/* + * Private slots + */ + +/// Show configuration for a channel. +void tcMainWindow::configureChannel(int channel) +{ + tcChannelManager* manager = m_globe->imagery()->channelManager(); + tcChannelConfigWidget* configWidget = manager->channel(channel)->configWidget(); + if (0 != configWidget) + { + configWidget->show(); + } +} diff --git a/tcMainWindow.h b/tcMainWindow.h index 804f6d2..7b70fb7 100644 --- a/tcMainWindow.h +++ b/tcMainWindow.h @@ -48,6 +48,15 @@ class tcMainWindow : public QMainWindow /// Destructor. virtual ~tcMainWindow(); + private slots: + + /* + * Private slots + */ + + /// Show configuration for a channel. + void configureChannel(int channel); + private: /* -- 2.11.4.GIT