bimedian_demosaic.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028
00029 #include <algorithm>
00030
00031 #include <libopenraw/demosaic.h>
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 static inline float
00043 m4 (float a, float b, float c, float d)
00044 {
00045 float t;
00046
00047
00048 if (a > b)
00049 {
00050 t = b;
00051 b = a;
00052 a = t;
00053 }
00054
00055 if (b > c)
00056 {
00057 t = c;
00058 c = b;
00059 if (a > t)
00060 {
00061 b = a;
00062 a = t;
00063 }
00064 else
00065 b = t;
00066 }
00067
00068 if (d >= c)
00069 return (b + c) / 2.0;
00070 else if (d >= a)
00071 return (b + d) / 2.0;
00072 else
00073 return (a + b) / 2.0;
00074 }
00075
00076
00077 #define ROW src_x
00078 #define COL 1
00079
00080
00081
00082
00083 void
00084 bimedian_demosaic (uint16_t *src, uint32_t src_x, uint32_t src_y,
00085 or_cfa_pattern pattern, uint8_t *dst)
00086 {
00087 uint32_t x,y;
00088 uint32_t offset, doffset;
00089 float *src_buf;
00090 float *dst_buf;
00091
00092 int npattern = 0;
00093 switch(pattern) {
00094 case OR_CFA_PATTERN_GRBG:
00095 npattern = 0;
00096 break;
00097 case OR_CFA_PATTERN_BGGR:
00098 npattern = 1;
00099 break;
00100 case OR_CFA_PATTERN_GBRG:
00101 npattern = 2;
00102 break;
00103 case OR_CFA_PATTERN_RGGB:
00104 npattern = 3;
00105 break;
00106 default:
00107 break;
00108 }
00109
00110 src_buf = (float*)calloc(src_x * src_y, sizeof(float));
00111 dst_buf = (float*)calloc(src_x * src_y * 3, sizeof(float));
00112
00113 std::copy(src, src + (src_x * src_y), src_buf);
00114
00115 offset = ROW + COL;
00116 doffset = 0;
00117 for(y = 1 ; y < src_y - 1; y++)
00118 {
00119 for (x = 1 ; x < src_x - 1; x++)
00120 {
00121 float red=0.0;
00122 float green=0.0;
00123 float blue=0.0;
00124
00125 if ((y + npattern%2)%2==0) {
00126 if ((x+npattern/2)%2==1) {
00127
00128
00129
00130
00131 blue =(src_buf[offset-COL]+src_buf[offset+COL])/2.0;
00132 green=src_buf[offset];
00133 red =(src_buf[offset-ROW]+src_buf[offset+ROW])/2.0;
00134 }
00135 else {
00136
00137
00138
00139
00140 blue =src_buf[offset];
00141 green=m4(src_buf[offset-ROW], src_buf[offset-COL],
00142 src_buf[offset+COL], src_buf[offset+ROW]);
00143 red =m4(src_buf[offset-ROW-COL], src_buf[offset-ROW+COL],
00144 src_buf[offset+ROW-COL], src_buf[offset+ROW+COL]);
00145 }
00146 }
00147 else {
00148 if ((x+npattern/2)%2==1) {
00149
00150
00151
00152
00153 blue =m4(src_buf[offset-ROW-COL], src_buf[offset-ROW+COL],
00154 src_buf[offset+ROW-COL], src_buf[offset+ROW+COL]);
00155 green=m4(src_buf[offset-ROW], src_buf[offset-COL],
00156 src_buf[offset+COL], src_buf[offset+ROW]);
00157 red =src_buf[offset];
00158 }
00159 else {
00160
00161
00162
00163
00164 blue =(src_buf[offset-ROW]+src_buf[offset+ROW])/2.0;
00165 green=src_buf[offset];
00166 red =(src_buf[offset-COL]+src_buf[offset+COL])/2.0;
00167 }
00168 }
00169
00170 dst_buf [doffset*3+0] = red / 16.0;
00171 dst_buf [doffset*3+1] = green / 16.0;
00172 dst_buf [doffset*3+2] = blue / 16.0;
00173
00174 offset++;
00175 doffset++;
00176 }
00177 offset+=2;
00178 }
00179 std::copy(dst_buf, dst_buf + (src_x * src_y * 3), dst);
00180 free(src_buf);
00181 free(dst_buf);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194