1 #if CN==1 2 3 #define T_MEAN float 4 #define F_ZERO (0.0f) 5 #define cnMode 1 6 7 #define frameToMean(a, b) (b) = *(a); 8 #define meanToFrame(a, b) *b = convert_uchar_sat(a); 9 10 inline float sum(float val) 11 { 12 return val; 13 } 14 15 #else 16 17 #define T_MEAN float4 18 #define F_ZERO (0.0f, 0.0f, 0.0f, 0.0f) 19 #define cnMode 4 20 21 #define meanToFrame(a, b)\ 22 b[0] = convert_uchar_sat(a.x); \ 23 b[1] = convert_uchar_sat(a.y); \ 24 b[2] = convert_uchar_sat(a.z); 25 26 #define frameToMean(a, b)\ 27 b.x = a[0]; \ 28 b.y = a[1]; \ 29 b.z = a[2]; \ 30 b.w = 0.0f; 31 32 inline float sum(const float4 val) 33 { 34 return (val.x + val.y + val.z); 35 } 36 37 #endif 38 39 __kernel void mog2_kernel(__global const uchar* frame, int frame_step, int frame_offset, int frame_row, int frame_col, //uchar || uchar3 40 __global uchar* modesUsed, //uchar 41 __global uchar* weight, //float 42 __global uchar* mean, //T_MEAN=float || float4 43 __global uchar* variance, //float 44 __global uchar* fgmask, int fgmask_step, int fgmask_offset, //uchar 45 float alphaT, float alpha1, float prune, 46 float c_Tb, float c_TB, float c_Tg, float c_varMin, //constants 47 float c_varMax, float c_varInit, float c_tau 48 #ifdef SHADOW_DETECT 49 , uchar c_shadowVal 50 #endif 51 ) 52 { 53 int x = get_global_id(0); 54 int y = get_global_id(1); 55 56 if( x < frame_col && y < frame_row) 57 { 58 __global const uchar* _frame = (frame + mad24(y, frame_step, mad24(x, CN, frame_offset))); 59 T_MEAN pix; 60 frameToMean(_frame, pix); 61 62 uchar foreground = 255; // 0 - the pixel classified as background 63 64 bool fitsPDF = false; //if it remains zero a new GMM mode will be added 65 66 int pt_idx = mad24(y, frame_col, x); 67 int idx_step = frame_row * frame_col; 68 69 __global uchar* _modesUsed = modesUsed + pt_idx; 70 uchar nmodes = _modesUsed[0]; 71 72 float totalWeight = 0.0f; 73 74 __global float* _weight = (__global float*)(weight); 75 __global float* _variance = (__global float*)(variance); 76 __global T_MEAN* _mean = (__global T_MEAN*)(mean); 77 78 uchar mode = 0; 79 for (; mode < nmodes; ++mode) 80 { 81 int mode_idx = mad24(mode, idx_step, pt_idx); 82 float c_weight = mad(alpha1, _weight[mode_idx], prune); 83 84 float c_var = _variance[mode_idx]; 85 86 T_MEAN c_mean = _mean[mode_idx]; 87 88 T_MEAN diff = c_mean - pix; 89 float dist2 = dot(diff, diff); 90 91 if (totalWeight < c_TB && dist2 < c_Tb * c_var) 92 foreground = 0; 93 94 if (dist2 < c_Tg * c_var) 95 { 96 fitsPDF = true; 97 c_weight += alphaT; 98 99 float k = alphaT / c_weight; 100 T_MEAN mean_new = mad((T_MEAN)-k, diff, c_mean); 101 float variance_new = clamp(mad(k, (dist2 - c_var), c_var), c_varMin, c_varMax); 102 103 for (int i = mode; i > 0; --i) 104 { 105 int prev_idx = mode_idx - idx_step; 106 if (c_weight < _weight[prev_idx]) 107 break; 108 109 _weight[mode_idx] = _weight[prev_idx]; 110 _variance[mode_idx] = _variance[prev_idx]; 111 _mean[mode_idx] = _mean[prev_idx]; 112 113 mode_idx = prev_idx; 114 } 115 116 _mean[mode_idx] = mean_new; 117 _variance[mode_idx] = variance_new; 118 _weight[mode_idx] = c_weight; //update weight by the calculated value 119 120 totalWeight += c_weight; 121 122 mode ++; 123 124 break; 125 } 126 if (c_weight < -prune) 127 c_weight = 0.0f; 128 129 _weight[mode_idx] = c_weight; //update weight by the calculated value 130 totalWeight += c_weight; 131 } 132 133 for (; mode < nmodes; ++mode) 134 { 135 int mode_idx = mad24(mode, idx_step, pt_idx); 136 float c_weight = mad(alpha1, _weight[mode_idx], prune); 137 138 if (c_weight < -prune) 139 { 140 c_weight = 0.0f; 141 nmodes = mode; 142 break; 143 } 144 _weight[mode_idx] = c_weight; //update weight by the calculated value 145 totalWeight += c_weight; 146 } 147 148 if (0.f < totalWeight) 149 { 150 totalWeight = 1.f / totalWeight; 151 for (int mode = 0; mode < nmodes; ++mode) 152 _weight[mad24(mode, idx_step, pt_idx)] *= totalWeight; 153 } 154 155 if (!fitsPDF) 156 { 157 uchar mode = nmodes == (NMIXTURES) ? (NMIXTURES) - 1 : nmodes++; 158 int mode_idx = mad24(mode, idx_step, pt_idx); 159 160 if (nmodes == 1) 161 _weight[mode_idx] = 1.f; 162 else 163 { 164 _weight[mode_idx] = alphaT; 165 166 for (int i = pt_idx; i < mode_idx; i += idx_step) 167 _weight[i] *= alpha1; 168 } 169 170 for (int i = nmodes - 1; i > 0; --i) 171 { 172 int prev_idx = mode_idx - idx_step; 173 if (alphaT < _weight[prev_idx]) 174 break; 175 176 _weight[mode_idx] = _weight[prev_idx]; 177 _variance[mode_idx] = _variance[prev_idx]; 178 _mean[mode_idx] = _mean[prev_idx]; 179 180 mode_idx = prev_idx; 181 } 182 183 _mean[mode_idx] = pix; 184 _variance[mode_idx] = c_varInit; 185 } 186 187 _modesUsed[0] = nmodes; 188 #ifdef SHADOW_DETECT 189 if (foreground) 190 { 191 float tWeight = 0.0f; 192 193 for (uchar mode = 0; mode < nmodes; ++mode) 194 { 195 int mode_idx = mad24(mode, idx_step, pt_idx); 196 T_MEAN c_mean = _mean[mode_idx]; 197 198 T_MEAN pix_mean = pix * c_mean; 199 200 float numerator = sum(pix_mean); 201 float denominator = dot(c_mean, c_mean); 202 203 if (denominator == 0) 204 break; 205 206 if (numerator <= denominator && numerator >= c_tau * denominator) 207 { 208 float a = numerator / denominator; 209 210 T_MEAN dD = mad(a, c_mean, -pix); 211 212 if (dot(dD, dD) < c_Tb * _variance[mode_idx] * a * a) 213 { 214 foreground = c_shadowVal; 215 break; 216 } 217 } 218 219 tWeight += _weight[mode_idx]; 220 if (tWeight > c_TB) 221 break; 222 } 223 } 224 #endif 225 __global uchar* _fgmask = fgmask + mad24(y, fgmask_step, x + fgmask_offset); 226 *_fgmask = (uchar)foreground; 227 } 228 } 229 230 __kernel void getBackgroundImage2_kernel(__global const uchar* modesUsed, 231 __global const uchar* weight, 232 __global const uchar* mean, 233 __global uchar* dst, int dst_step, int dst_offset, int dst_row, int dst_col, 234 float c_TB) 235 { 236 int x = get_global_id(0); 237 int y = get_global_id(1); 238 239 if(x < dst_col && y < dst_row) 240 { 241 int pt_idx = mad24(y, dst_col, x); 242 243 __global const uchar* _modesUsed = modesUsed + pt_idx; 244 uchar nmodes = _modesUsed[0]; 245 246 T_MEAN meanVal = (T_MEAN)F_ZERO; 247 248 float totalWeight = 0.0f; 249 __global const float* _weight = (__global const float*)weight; 250 __global const T_MEAN* _mean = (__global const T_MEAN*)(mean); 251 int idx_step = dst_row * dst_col; 252 for (uchar mode = 0; mode < nmodes; ++mode) 253 { 254 int mode_idx = mad24(mode, idx_step, pt_idx); 255 float c_weight = _weight[mode_idx]; 256 T_MEAN c_mean = _mean[mode_idx]; 257 258 meanVal = mad(c_weight, c_mean, meanVal); 259 260 totalWeight += c_weight; 261 262 if (totalWeight > c_TB) 263 break; 264 } 265 266 if (0.f < totalWeight) 267 meanVal = meanVal / totalWeight; 268 else 269 meanVal = (T_MEAN)(0.f); 270 __global uchar* _dst = dst + mad24(y, dst_step, mad24(x, CN, dst_offset)); 271 meanToFrame(meanVal, _dst); 272 } 273 }