Malvar-He-Cutler Linear Image Demosaicking
|
00001 00051 void MalvarDemosaic(float *Output, const float *Input, int Width, int Height, 00052 int RedX, int RedY) 00053 { 00054 const int BlueX = 1 - RedX; 00055 const int BlueY = 1 - RedY; 00056 float *OutputRed = Output; 00057 float *OutputGreen = Output + Width*Height; 00058 float *OutputBlue = Output + 2*Width*Height; 00059 /* Neigh holds a copy of the 5x5 neighborhood around the current point */ 00060 float Neigh[5][5]; 00061 /* NeighPresence is used for boundary handling. It is set to 0 if the 00062 neighbor is beyond the boundaries of the image and 1 otherwise. */ 00063 int NeighPresence[5][5]; 00064 int i, j, x, y, nx, ny; 00065 00066 00067 for(y = 0, i = 0; y < Height; y++) 00068 { 00069 for(x = 0; x < Width; x++, i++) 00070 { 00071 /* 5x5 neighborhood around the point (x,y) is copied into Neigh */ 00072 for(ny = -2, j = x + Width*(y - 2); ny <= 2; ny++, j += Width) 00073 { 00074 for(nx = -2; nx <= 2; nx++) 00075 { 00076 if(0 <= x + nx && x + nx < Width 00077 && 0 <= y + ny && y + ny < Height) 00078 { 00079 Neigh[2 + nx][2 + ny] = Input[j + nx]; 00080 NeighPresence[2 + nx][2 + ny] = 1; 00081 } 00082 else 00083 { 00084 Neigh[2 + nx][2 + ny] = 0; 00085 NeighPresence[2 + nx][2 + ny] = 0; 00086 } 00087 } 00088 } 00089 00090 if((x & 1) == RedX && (y & 1) == RedY) 00091 { 00092 /* Center pixel is red */ 00093 OutputRed[i] = Input[i]; 00094 OutputGreen[i] = (2*(Neigh[2][1] + Neigh[1][2] 00095 + Neigh[3][2] + Neigh[2][3]) 00096 + (NeighPresence[0][2] + NeighPresence[4][2] 00097 + NeighPresence[2][0] + NeighPresence[2][4])*Neigh[2][2] 00098 - Neigh[0][2] - Neigh[4][2] 00099 - Neigh[2][0] - Neigh[2][4]) 00100 / (2*(NeighPresence[2][1] + NeighPresence[1][2] 00101 + NeighPresence[3][2] + NeighPresence[2][3])); 00102 OutputBlue[i] = (4*(Neigh[1][1] + Neigh[3][1] 00103 + Neigh[1][3] + Neigh[3][3]) + 00104 3*((NeighPresence[0][2] + NeighPresence[4][2] 00105 + NeighPresence[2][0] + NeighPresence[2][4])*Neigh[2][2] 00106 - Neigh[0][2] - Neigh[4][2] 00107 - Neigh[2][0] - Neigh[2][4])) 00108 / (4*(NeighPresence[1][1] + NeighPresence[3][1] 00109 + NeighPresence[1][3] + NeighPresence[3][3])); 00110 } 00111 else if((x & 1) == BlueX && (y & 1) == BlueY) 00112 { 00113 /* Center pixel is blue */ 00114 OutputBlue[i] = Input[i]; 00115 OutputGreen[i] = (2*(Neigh[2][1] + Neigh[1][2] 00116 + Neigh[3][2] + Neigh[2][3]) 00117 + (NeighPresence[0][2] + NeighPresence[4][2] 00118 + NeighPresence[2][0] + NeighPresence[2][4])*Neigh[2][2] 00119 - Neigh[0][2] - Neigh[4][2] 00120 - Neigh[2][0] - Neigh[2][4]) 00121 / (2*(NeighPresence[2][1] + NeighPresence[1][2] 00122 + NeighPresence[3][2] + NeighPresence[2][3])); 00123 OutputRed[i] = (4*(Neigh[1][1] + Neigh[3][1] 00124 + Neigh[1][3] + Neigh[3][3]) + 00125 3*((NeighPresence[0][2] + NeighPresence[4][2] 00126 + NeighPresence[2][0] + NeighPresence[2][4])*Neigh[2][2] 00127 - Neigh[0][2] - Neigh[4][2] 00128 - Neigh[2][0] - Neigh[2][4])) 00129 / (4*(NeighPresence[1][1] + NeighPresence[3][1] 00130 + NeighPresence[1][3] + NeighPresence[3][3])); 00131 } 00132 else 00133 { 00134 /* Center pixel is green */ 00135 OutputGreen[i] = Input[i]; 00136 00137 if((y & 1) == RedY) 00138 { 00139 /* Left and right neighbors are red */ 00140 OutputRed[i] = (8*(Neigh[1][2] + Neigh[3][2]) 00141 + (2*(NeighPresence[1][1] + NeighPresence[3][1] 00142 + NeighPresence[0][2] + NeighPresence[4][2] 00143 + NeighPresence[1][3] + NeighPresence[3][3]) 00144 - NeighPresence[2][0] - NeighPresence[2][4])*Neigh[2][2] 00145 - 2*(Neigh[1][1] + Neigh[3][1] 00146 + Neigh[0][2] + Neigh[4][2] 00147 + Neigh[1][3] + Neigh[3][3]) 00148 + Neigh[2][0] + Neigh[2][4]) 00149 / (8*(NeighPresence[1][2] + NeighPresence[3][2])); 00150 OutputBlue[i] = (8*(Neigh[2][1] + Neigh[2][3]) 00151 + (2*(NeighPresence[1][1] + NeighPresence[3][1] 00152 + NeighPresence[2][0] + NeighPresence[2][4] 00153 + NeighPresence[1][3] + NeighPresence[3][3]) 00154 - NeighPresence[0][2] - NeighPresence[4][2])*Neigh[2][2] 00155 - 2*(Neigh[1][1] + Neigh[3][1] 00156 + Neigh[2][0] + Neigh[2][4] 00157 + Neigh[1][3] + Neigh[3][3]) 00158 + Neigh[0][2] + Neigh[4][2]) 00159 / (8*(NeighPresence[2][1] + NeighPresence[2][3])); 00160 } 00161 else 00162 { 00163 /* Left and right neighbors are blue */ 00164 OutputRed[i] = (8*(Neigh[2][1] + Neigh[2][3]) 00165 + (2*(NeighPresence[1][1] + NeighPresence[3][1] 00166 + NeighPresence[2][0] + NeighPresence[2][4] 00167 + NeighPresence[1][3] + NeighPresence[3][3]) 00168 - NeighPresence[0][2] - NeighPresence[4][2])*Neigh[2][2] 00169 - 2*(Neigh[1][1] + Neigh[3][1] 00170 + Neigh[2][0] + Neigh[2][4] 00171 + Neigh[1][3] + Neigh[3][3]) 00172 + Neigh[0][2] + Neigh[4][2]) 00173 / (8*(NeighPresence[2][1] + NeighPresence[2][3])); 00174 OutputBlue[i] = (8*(Neigh[1][2] + Neigh[3][2]) 00175 + (2*(NeighPresence[1][1] + NeighPresence[3][1] 00176 + NeighPresence[0][2] + NeighPresence[4][2] 00177 + NeighPresence[1][3] + NeighPresence[3][3]) 00178 - NeighPresence[2][0] - NeighPresence[2][4])*Neigh[2][2] 00179 - 2*(Neigh[1][1] + Neigh[3][1] 00180 + Neigh[0][2] + Neigh[4][2] 00181 + Neigh[1][3] + Neigh[3][3]) 00182 + Neigh[2][0] + Neigh[2][4]) 00183 / (8*(NeighPresence[1][2] + NeighPresence[3][2])); 00184 } 00185 } 00186 } 00187 } 00188 }