ImageMapper.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  ImageMapper.cpp
00037 // Author:    Pedram Azad
00038 // Date:      04.10.2008
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs
00047 
00048 #include "ImageMapper.h"
00049 
00050 #include "Image/ByteImage.h"
00051 #include "Image/ImageProcessor.h"
00052 #include "Calibration/Calibration.h"
00053 #include "Helpers/helpers.h"
00054 
00055 #include <stdio.h>
00056 #include <math.h>
00057 
00058 
00059 
00060 // ****************************************************************************
00061 // Constructor / Destructor
00062 // ****************************************************************************
00063 
00064 CImageMapper::CImageMapper(bool bInterpolate)
00065 {
00066         m_bInterpolate = bInterpolate;
00067 
00068         m_pOffsetMap = 0;
00069         m_pCoordinateMap = 0;
00070         
00071         width = height = 0;
00072 
00073         m_bMapComputed = false;
00074 }
00075 
00076 CImageMapper::~CImageMapper()
00077 {
00078         if (m_pOffsetMap)
00079                 delete [] m_pOffsetMap;
00080 
00081         if (m_pCoordinateMap)
00082                 delete [] m_pCoordinateMap;
00083 }
00084 
00085 
00086 // ****************************************************************************
00087 // Methods
00088 // ****************************************************************************
00089 
00090 void CImageMapper::ComputeMap(int width, int height)
00091 {
00092         if (width != this->width || height != this->height)
00093         {
00094                 this->width = width;
00095                 this->height = height;
00096         
00097                 if (m_pOffsetMap)
00098                         delete [] m_pOffsetMap;
00099         
00100                 m_pOffsetMap = new int[width * height];
00101         
00102                 if (m_bInterpolate)
00103                 {
00104                         if (m_pCoordinateMap)
00105                                 delete [] m_pCoordinateMap;
00106                         
00107                         m_pCoordinateMap = new MapCoordinates[width * height];
00108                 }
00109         }
00110         
00111         // compute map
00112         for (int i = 0, offset = 0; i < height; i++)
00113         {
00114                 for (int j = 0; j < width; j++, offset++)
00115                 {
00116                         const Vec2d newCoordinates = { float(j), float(i) };
00117                         
00118                         // call virtual method
00119                         Vec2d originalCoordinates;
00120                         ComputeOriginalCoordinates(newCoordinates, originalCoordinates);
00121 
00122                         const float u = originalCoordinates.x;
00123                         const float v = originalCoordinates.y;
00124 
00125                         const int u_int = m_bInterpolate ? int(floor(u)) : my_round(u);
00126                         const int v_int = m_bInterpolate ? int(floor(v)) : my_round(v);
00127 
00128                         if (u_int >= 0 && u_int < width - 1 && v_int >= 0 && v_int < height - 1)
00129                         {
00130                                 m_pOffsetMap[offset] = v_int * width + u_int;
00131 
00132                                 if (m_bInterpolate)
00133                                 {
00134                                         const int u1 = int(floor(u));
00135                                         const int v1 = int(floor(v));
00136                                         const float x = u - u1;
00137                                         const float y = v - v1;
00138                                 
00139                                         const float f00 = (1 - x) * (1 - y);
00140                                         const float f10 = x * (1 - y);
00141                                         const float f01 = (1 - x) * y;
00142                                         const float f11 = x * y;
00143 
00144                                         const float sum = f00 + f10 + f01 + f11;
00145 
00146                                         // 2^22 = 4194304
00147                                         m_pCoordinateMap[offset].f00 = int((f00 / sum) * 4194304);
00148                                         m_pCoordinateMap[offset].f10 = int((f10 / sum) * 4194304);
00149                                         m_pCoordinateMap[offset].f01 = int((f01 / sum) * 4194304);
00150                                         m_pCoordinateMap[offset].f11 = int((f11 / sum) * 4194304);
00151                                 }
00152                         }
00153                         else
00154                         {
00155                                 m_pOffsetMap[offset] = 0;
00156                                 
00157                                 if (m_bInterpolate)
00158                                 {
00159                                         m_pCoordinateMap[offset].f00 = 0;
00160                                         m_pCoordinateMap[offset].f10 = 0;
00161                                         m_pCoordinateMap[offset].f01 = 0;
00162                                         m_pCoordinateMap[offset].f11 = 0;
00163                                 }
00164                         }
00165                 }
00166         }
00167 
00168         m_bMapComputed = true;
00169 }
00170 
00171 void CImageMapper::PerformMapping(const CByteImage *pInputImage, CByteImage *pOutputImage)
00172 {
00173         if (!m_bMapComputed)
00174         {
00175                 printf("error: map has not been computed yet. call CImageMapper::ComputeMap\n");
00176                 return;
00177         }
00178 
00179         if (pInputImage->type != pOutputImage->type)
00180         {
00181                 printf("error: input and output image must be of same type for CImageMapper::PerformMapping\n");
00182                 return;
00183         }
00184 
00185         if (pInputImage->width != width || pInputImage->height != height)
00186         {
00187                 printf("error: input image does not match calibration file for CImageMapper::PerformMapping\n");
00188                 return;
00189         }
00190 
00191         if (pOutputImage->width != width || pOutputImage->height != height)
00192         {
00193                 printf("error: output image does not match calibration file for CImageMapper::PerformMapping\n");
00194                 return;
00195         }
00196 
00197         CByteImage *pSaveOutputImage = 0;
00198         if (pInputImage->pixels == pOutputImage->pixels)
00199         {
00200                 pSaveOutputImage = pOutputImage;
00201                 pOutputImage = new CByteImage(pInputImage);
00202         }
00203 
00204         unsigned char *input = pInputImage->pixels;
00205         unsigned char *output = pOutputImage->pixels;
00206 
00207         const int nPixels = width * height;
00208 
00209         if (pInputImage->type == CByteImage::eGrayScale)
00210         {
00211                 const unsigned char g = input[0];
00212                 input[0] = 0;
00213 
00214                 if (m_bInterpolate)
00215                 {
00216                         for (int i = 0; i < nPixels; i++)
00217                         {
00218                                 const int input_offset = m_pOffsetMap[i];
00219                                 const MapCoordinates &m = m_pCoordinateMap[i];
00220                                 output[i] = (unsigned char) ((input[input_offset] * m.f00 + input[input_offset + width] * m.f01 + input[input_offset + 1] * m.f10 + input[input_offset + width + 1] * m.f11 + 2097152) >> 22);
00221                         }
00222                 }
00223                 else
00224                 {
00225                         for (int i = 0; i < nPixels; i++)
00226                                 output[i] = input[m_pOffsetMap[i]];
00227                 }
00228 
00229                 input[0] = g;
00230         }
00231         else if (pInputImage->type == CByteImage::eRGB24)
00232         {
00233                 const unsigned char r = input[0];
00234                 const unsigned char g = input[1];
00235                 const unsigned char b = input[2];
00236                 input[0] = input[1] = input[2] = 0;
00237 
00238                 if (m_bInterpolate)
00239                 {
00240                         for (int i = 0, output_offset = 0; i < nPixels; i++, output_offset += 3)
00241                         {
00242                                 const int input_offset = 3 * m_pOffsetMap[i];
00243                                 const int width3 = 3 * width;
00244 
00245                                 const MapCoordinates &m = m_pCoordinateMap[i];
00246                                 
00247                                 output[output_offset] = (unsigned char) ((input[input_offset] * m.f00 + input[input_offset + width3] * m.f01 + input[input_offset + 3] * m.f10 + input[input_offset + width3 + 3] * m.f11 + 2097152) >> 22);
00248                                 output[output_offset + 1] = (unsigned char) ((input[input_offset + 1] * m.f00 + input[input_offset + width3 + 1] * m.f01 + input[input_offset + 4] * m.f10 + input[input_offset + width3 + 4] * m.f11 + 2097152) >> 22);
00249                                 output[output_offset + 2] = (unsigned char) ((input[input_offset + 2] * m.f00 + input[input_offset + width3 + 2] * m.f01 + input[input_offset + 5] * m.f10 + input[input_offset + width3 + 5] * m.f11 + 2097152) >> 22);
00250                         }
00251                 }
00252                 else
00253                 {
00254                         for (int i = 0, output_offset = 0; i < nPixels; i++, output_offset += 3)
00255                         {
00256                                 const int input_offset = 3 * m_pOffsetMap[i];
00257                                 output[output_offset] = input[input_offset];
00258                                 output[output_offset + 1] = input[input_offset + 1];
00259                                 output[output_offset + 2] = input[input_offset + 2];
00260                         }
00261                 }
00262 
00263                 input[0] = r;
00264                 input[1] = g;
00265                 input[2] = b;
00266         }
00267 
00268         if (pSaveOutputImage)
00269         {
00270                 ImageProcessor::CopyImage(pOutputImage, pSaveOutputImage);
00271                 delete pOutputImage;
00272         }
00273 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57