Image Interpolation with Contour Stencils

fitsten.c

Go to the documentation of this file.
00001 
00016 #include <stdlib.h>
00017 #include "fitsten.h"
00018 
00019 
00020 #define PIXEL_STRIDE    3
00021 
00022 /* Constants related to stencil edge weights */
00023 /* mu = 3/4 * sqrt(2) */
00024 #define W_MU        (1.060660171779821)
00025 /* Divisor for axial stencils = 6 */
00026 #define W_PI_2      (6.0)
00027 /* Divisor for diagonal stencils = 4 sqrt(2) */
00028 #define W_PI_4      (5.656854249492381)
00029 /* Divisor for pi/8 stencils = 6(1 + sqrt(2))sqrt(2 - sqrt(2)) + 12 */
00030 #define W_PI_8      (23.086554390135440)
00031 
00032 
00033 
00035 static int Dist(int32_t *A, int32_t *B)
00036 {
00037     int iDistR = A[0] - B[0];
00038     int iDistG = A[1] - B[1];
00039     int iDistB = A[2] - B[2];
00040     register int iDistY = 2*iDistR + 4*iDistG + iDistB;
00041     register int iDistU = -iDistR - 2*iDistG + 3*iDistB;
00042     register int iDistV = 4*iDistR - 3*iDistG - iDistB;
00043     return (abs(iDistY) + abs(iDistU) + abs(iDistV)) >> 4;
00044 }
00045 
00046 
00070 int FitStencils(int *Stencil, int32_t *Image, int Width, int Height, int StencilMul)
00071 {
00072     const int Stride = PIXEL_STRIDE*Width;
00073     const int TVStride = 8*Width;
00074     int *StencilTv; /* Contour stencil total variations estimates TV[S]            */
00075     int Dh[3][2];   /* Horizontal differences computed over the current 3x3 window */
00076     int Dv[2][3];   /* Vertical differences                                        */
00077     int Da[2][2];   /* Diagonal differences |Image(m,n) - Image(m+1,n+1)|          */
00078     int Db[2][2];   /* Diagonal differences |Image(m+1,n) - Image(m,n+1)|          */
00079     int *TvPtr, TvMin, Temp;
00080     int x, y, k, S;
00081 
00082     
00083     if(!(StencilTv = (int *)malloc(sizeof(int)*8*Width*Height)))
00084         return 0;
00085     
00086     TvPtr = StencilTv;
00087     
00088     for(y = 0; y < Height; y++)
00089     {
00090         Dh[0][1] = 0;
00091         Dh[1][1] = 0;
00092         Dh[2][1] = 0;
00093         
00094         Dv[0][1] = 0;
00095         Dv[1][1] = 0;
00096         Dv[0][2] = (y > 0) ? Dist(Image - Stride, Image) : 0;
00097         Dv[1][2] = (y < Height-1) ? Dist(Image + Stride, Image) : 0;
00098         
00099         Da[0][1] = 0;
00100         Da[1][1] = 0;
00101         Db[0][1] = 0;
00102         Db[1][1] = 0;
00103     
00104         for(x = 0; x < Width; x++, Image += PIXEL_STRIDE, TvPtr += 8)
00105         {
00106             Dh[0][0] = Dh[0][1];
00107             Dh[1][0] = Dh[1][1];
00108             Dh[2][0] = Dh[2][1];
00109             
00110             Dv[0][0] = Dv[0][1];
00111             Dv[1][0] = Dv[1][1];
00112             Dv[0][1] = Dv[0][2];
00113             Dv[1][1] = Dv[1][2];
00114             
00115             Da[0][0] = Da[0][1];
00116             Da[1][0] = Da[1][1];
00117             
00118             Db[0][0] = Db[0][1];
00119             Db[1][0] = Db[1][1];
00120             
00121             if(x < Width-1)
00122             {
00123                 Dh[1][1] = Dist(Image, Image+PIXEL_STRIDE);
00124             
00125                 if(y > 0)
00126                 {
00127                     Dh[0][1] = Dist(Image-Stride, Image-Stride+PIXEL_STRIDE);
00128                     Dv[0][2] = Dist(Image-Stride+PIXEL_STRIDE, Image+PIXEL_STRIDE);
00129                     Da[0][1] = Dist(Image-Stride, Image+PIXEL_STRIDE);
00130                     Db[0][1] = Dist(Image-Stride+PIXEL_STRIDE, Image);
00131                 }
00132                 
00133                 if(y < Height-1)
00134                 {
00135                     Dh[2][1] = Dist(Image+Stride, Image+Stride+PIXEL_STRIDE);
00136                     Dv[1][2] = Dist(Image+PIXEL_STRIDE, Image+Stride+PIXEL_STRIDE);
00137                     Da[1][1] = Dist(Image, Image+Stride+PIXEL_STRIDE);
00138                     Db[1][1] = Dist(Image+PIXEL_STRIDE, Image+Stride);
00139                 }
00140             }
00141             else
00142             {
00143                 Dh[0][1] = 0;
00144                 Dh[1][1] = 0;
00145                 Dh[2][1] = 0;
00146                 
00147                 Dv[0][2] = 0;
00148                 Dv[1][2] = 0;
00149                 
00150                 Da[0][1] = 0;
00151                 Da[1][1] = 0;
00152                 
00153                 Db[0][1] = 0;
00154                 Db[1][1] = 0;
00155             }
00156 
00157             TvPtr[1] = (Db[1][0] + Db[0][1]) + Db[0][0] + Db[1][1];
00158             TvPtr[3] = (Dh[1][0] + Dh[1][1]) + Dh[0][0] + Dh[0][1] + Dh[2][0] + Dh[2][1];
00159             TvPtr[5] = (Da[0][0] + Da[1][1]) + Da[1][0] + Da[0][1];
00160             TvPtr[7] = (Dv[0][1] + Dv[1][1]) + Dv[0][0] + Dv[1][0] + Dv[0][2] + Dv[1][2];
00161         
00162             TvPtr[0] = (int)((TvPtr[7] + TvPtr[1]*W_MU) / W_PI_8 + 0.5);
00163             TvPtr[2] = (int)((TvPtr[1]*W_MU + TvPtr[3]) / W_PI_8 + 0.5);
00164             TvPtr[4] = (int)((TvPtr[3] + TvPtr[5]*W_MU) / W_PI_8 + 0.5);
00165             TvPtr[6] = (int)((TvPtr[5]*W_MU + TvPtr[7]) / W_PI_8 + 0.5);
00166             
00167             TvPtr[1] = (int)(TvPtr[1] / W_PI_4 + 0.5);
00168             TvPtr[3] = (int)(TvPtr[3] / W_PI_2 + 0.5);
00169             TvPtr[5] = (int)(TvPtr[5] / W_PI_4 + 0.5);
00170             TvPtr[7] = (int)(TvPtr[7] / W_PI_2 + 0.5);
00171         }
00172     }
00173     
00174     TvPtr = StencilTv;
00175     
00176     for(y = 0; y < Height; y++)
00177     {
00178         for(x = 0; x < Width; x++, TvPtr += 8, Stencil++)
00179         {
00180             if(1 <= x && x < Width - 1 && 1 <= y && y < Height - 1)
00181             {
00182                 /* Filter the TV estimates by [1,2,1; 2,4,2; 1,2,1] */
00183                 TvMin = TvPtr[-TVStride - 8] + TvPtr[-TVStride + 8]
00184                         + TvPtr[TVStride - 8] + TvPtr[TVStride + 8]
00185                         + ((TvPtr[-TVStride] + TvPtr[-8]
00186                         + TvPtr[8] + TvPtr[TVStride]) << 1)
00187                         + (TvPtr[0] << 2);
00188                 S = 0;
00189             
00190                 for(k = 1; k < 8; k++)
00191                 {
00192                     Temp = TvPtr[k - TVStride - 8] + TvPtr[k - TVStride + 8]
00193                         + TvPtr[k + TVStride - 8] + TvPtr[k + TVStride + 8]
00194                         + ((TvPtr[k - TVStride] + TvPtr[k - 8]
00195                         + TvPtr[k + 8] + TvPtr[k + TVStride]) << 1)
00196                         + (TvPtr[k] << 2);
00197                     
00198                     if(Temp < TvMin)
00199                     {
00200                         TvMin = Temp;
00201                         S = k;
00202                     }
00203                         
00204                 }
00205             }
00206             else
00207             {
00208                 TvMin = TvPtr[0];
00209                 S = 0;
00210                 
00211                 for(k = 1; k < 8; k++)
00212                     if(TvPtr[k] < TvMin)
00213                         TvMin = TvPtr[S = k];
00214             }
00215             
00216             *Stencil = StencilMul * S;
00217         }
00218     }
00219     
00220     free(StencilTv);
00221     return 1;
00222 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines