imageWarper.h
Go to the documentation of this file.00001
00015 #ifndef DLR_COMPUTERVISION_IMAGEWARPER_H
00016 #define DLR_COMPUTERVISION_IMAGEWARPER_H
00017
00018 #include <dlrComputerVision/image.h>
00019 #include <dlrNumeric/array2D.h>
00020
00021 namespace dlr {
00022
00023 namespace computerVision {
00024
00027 template <class NumericType, class TransformFunctor>
00028 class ImageWarper
00029 {
00030 public:
00031
00032
00033
00037 ImageWarper();
00038
00039
00053 ImageWarper(size_t inputRows, size_t inputColumns,
00054 size_t outputRows, size_t outputColumns,
00055 TransformFunctor transformer);
00056
00057
00062 virtual
00063 ~ImageWarper();
00064
00065
00075 template <ImageFormat InputFormat, ImageFormat OutputFormat>
00076 Image<OutputFormat>
00077 warpImage(Image<InputFormat> const& inputImage,
00078 typename Image<OutputFormat>::PixelType defaultValue) const;
00079
00080 private:
00081
00082 struct SampleInfo {
00083 NumericType c00;
00084 NumericType c01;
00085 NumericType c10;
00086 NumericType c11;
00087 size_t index00;
00088 bool isInBounds;
00089 };
00090
00091 size_t m_inputColumns;
00092 size_t m_inputRows;
00093 Array2D<SampleInfo> m_lookupTable;
00094
00095 };
00096
00097 }
00098
00099 }
00100
00101
00102
00103
00104 #include <dlrNumeric/vector2D.h>
00105
00106 namespace dlr {
00107
00108 namespace computerVision {
00109
00110
00111 template<class NumericType, class TransformFunctor>
00112 ImageWarper<NumericType, TransformFunctor>::
00113 ImageWarper()
00114 : m_inputColumns(0),
00115 m_inputRows(0),
00116 m_lookupTable()
00117 {
00118
00119 }
00120
00121
00122 template<class NumericType, class TransformFunctor>
00123 ImageWarper<NumericType, TransformFunctor>::
00124 ImageWarper(size_t inputRows, size_t inputColumns,
00125 size_t outputRows, size_t outputColumns,
00126 TransformFunctor transformer)
00127 : m_inputColumns(inputColumns),
00128 m_inputRows(inputRows),
00129 m_lookupTable(outputRows, outputColumns)
00130 {
00131
00132 for(size_t row = 0; row < outputRows; ++row) {
00133 for(size_t column = 0; column < outputColumns; ++column) {
00134 numeric::Vector2D outputCoord(column, row);
00135 numeric::Vector2D inputCoord = transformer(outputCoord);
00136 SampleInfo& sampleInfo = m_lookupTable(row, column);
00137 if((inputCoord.y() >= 0.0)
00138 && (inputCoord.x() >= 0.0)
00139 && (inputCoord.y() < static_cast<double>(inputRows - 1))
00140 && (inputCoord.x() < static_cast<double>(inputColumns - 1))) {
00141 double tmpDbl;
00142 double xFrac = modf(inputCoord.x(), &tmpDbl);
00143 size_t i0 = static_cast<size_t>(tmpDbl);
00144 double yFrac = modf(inputCoord.y(), &tmpDbl);
00145 size_t j0 = static_cast<size_t>(tmpDbl);
00146 double oneMinusXFrac = 1.0 - xFrac;
00147 double oneMinusYFrac = 1.0 - yFrac;
00148 sampleInfo.c00 = oneMinusXFrac * oneMinusYFrac;
00149 sampleInfo.c01 = xFrac * oneMinusYFrac;
00150 sampleInfo.c10 = oneMinusXFrac * yFrac;
00151 sampleInfo.c11 = xFrac * yFrac;
00152 sampleInfo.index00 = inputColumns * j0 + i0;
00153 sampleInfo.isInBounds = true;
00154 } else {
00155 sampleInfo.isInBounds = false;
00156 }
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164 template<class NumericType, class TransformFunctor>
00165 ImageWarper<NumericType, TransformFunctor>::
00166 ~ImageWarper()
00167 {
00168
00169 }
00170
00171
00172
00173 template<class NumericType, class TransformFunctor>
00174 template <ImageFormat InputFormat, ImageFormat OutputFormat>
00175 Image<OutputFormat>
00176 ImageWarper<NumericType, TransformFunctor>::
00177 warpImage(Image<InputFormat> const& inputImage,
00178 typename Image<OutputFormat>::PixelType defaultValue) const
00179 {
00180 if((inputImage.rows() != m_inputRows)
00181 || (inputImage.columns() != m_inputColumns)) {
00182 std::ostringstream message;
00183 message
00184 << "InputImage (" << inputImage.rows() << "x" << inputImage.columns()
00185 << ") doesn't match expected dimensions (" << m_inputRows << "x"
00186 << m_inputColumns << ").";
00187 DLR_THROW(ValueException, "ImageWarper::warpImage()",
00188 message.str().c_str());
00189 }
00190 Image<OutputFormat> outputImage(
00191 m_lookupTable.rows(), m_lookupTable.columns());
00192 for(size_t ii = 0; ii < m_lookupTable.size(); ++ii) {
00193 SampleInfo const& sampleInfo = m_lookupTable(ii);
00194 if(sampleInfo.isInBounds) {
00195 typename Image<OutputFormat>::PixelType& outputPixel =
00196 outputImage[ii];
00197 size_t inputIndex = sampleInfo.index00;
00198
00199 outputPixel = sampleInfo.c00 * inputImage[inputIndex];
00200 ++inputIndex;
00201 outputPixel += sampleInfo.c01 * inputImage[inputIndex];
00202 inputIndex += m_inputColumns;
00203 outputPixel += sampleInfo.c11 * inputImage[inputIndex];
00204 --inputIndex;
00205 outputPixel += sampleInfo.c10 * inputImage[inputIndex];
00206 } else {
00207 outputImage[ii] = defaultValue;
00208 }
00209 }
00210 return outputImage;
00211 }
00212
00213 }
00214
00215 }
00216
00217 #endif