void BGModelMog::Init() { MOGDATA *pMOG = m_pMOG; int *pK = m_pK; Image<BYTERGB> prgbSrc(m_SrcImage); int n = 0; for(int i = 0; i < m_height; i++) { for(int j = 0; j < m_width; j++) { pMOG[0].mu.Red = prgbSrc[i][j].Red; pMOG[0].mu.Green = prgbSrc[i][j].Green; pMOG[0].mu.Blue = prgbSrc[i][j].Blue; pMOG[0].var.Red = m_noise; pMOG[0].var.Green = m_noise; pMOG[0].var.Blue = m_noise; pMOG[0].w = 1.0; pMOG[0].sortKey = pMOG[0].w/sqrt(pMOG[0].var.Red+pMOG[0].var.Green+pMOG[0].var.Blue); pK[n] = 1; n++; pMOG += NUMBERGAUSSIANS; } } return; }
void BGModelGauss::Init() { DBLRGB *pMu = m_pMu; DBLRGB *pVar = m_pVar; Image<BYTERGB> prgbSrc(m_SrcImage); for(int i = 0; i < m_height; i++) { for(int j = 0; j < m_width; j++) { pMu->Red = prgbSrc[i][j].Red; pMu->Green = prgbSrc[i][j].Green; pMu->Blue = prgbSrc[i][j].Blue; pVar->Red = m_noise; pVar->Green = m_noise; pVar->Blue = m_noise; pMu++; pVar++; } } return; }
void BGModelFuzzySom::Init() { Image<BYTERGB> prgbSrc(m_SrcImage); for(int j = 0; j < m_height; j++) { int jj = m_offset + j*(N + m_pad); for(int i = 0; i < m_width; i++) { int ii = m_offset + i*(M + m_pad); for(int l = 0; l < N; l++) { for(int k = 0; k < M; k++) { m_ppSOM[jj+l][ii+k].Red = (double)prgbSrc[j][i].Red; m_ppSOM[jj+l][ii+k].Green = (double)prgbSrc[j][i].Green; m_ppSOM[jj+l][ii+k].Blue = (double)prgbSrc[j][i].Blue; } } } } m_K = 0; return; }
void BGModelMog::Update() { int kBG; MOGDATA *pMOG = m_pMOG; int *pK = m_pK; Image<BYTERGB> prgbSrc(m_SrcImage); Image<BYTERGB> prgbBG(m_BGImage); Image<BYTERGB> prgbFG(m_FGImage); int n = 0; for(int i = 0; i < m_height; i++) { for(int j = 0; j < m_width; j++) { double srcR = (double) prgbSrc[i][j].Red; double srcG = (double) prgbSrc[i][j].Green; double srcB = (double) prgbSrc[i][j].Blue; // Find matching distribution int kHit = -1; for(int k = 0; k < pK[n]; k++) { // Mahalanobis distance double dr = srcR - pMOG[k].mu.Red; double dg = srcG - pMOG[k].mu.Green; double db = srcB - pMOG[k].mu.Blue; double d2 = dr*dr/pMOG[k].var.Red + dg*dg/pMOG[k].var.Green + db*db/pMOG[k].var.Blue; if(d2 < m_threshold) { kHit = k; break; } } // Adjust parameters // matching distribution found if(kHit != -1) { for(int k = 0; k < pK[n]; k++) { if(k == kHit) { pMOG[k].w = pMOG[k].w + m_alpha*(1.0f - pMOG[k].w); double d; d = srcR - pMOG[k].mu.Red; if(d*d > DBL_MIN) pMOG[k].mu.Red += m_alpha*d; d = srcG - pMOG[k].mu.Green; if(d*d > DBL_MIN) pMOG[k].mu.Green += m_alpha*d; d = srcB - pMOG[k].mu.Blue; if(d*d > DBL_MIN) pMOG[k].mu.Blue += m_alpha*d; d = (srcR - pMOG[k].mu.Red)*(srcR - pMOG[k].mu.Red) - pMOG[k].var.Red; if(d*d > DBL_MIN) pMOG[k].var.Red += m_alpha*d; d = (srcG - pMOG[k].mu.Green)*(srcG - pMOG[k].mu.Green) - pMOG[k].var.Green; if(d*d > DBL_MIN) pMOG[k].var.Green += m_alpha*d; d = (srcB - pMOG[k].mu.Blue)*(srcB - pMOG[k].mu.Blue) - pMOG[k].var.Blue; if(d*d > DBL_MIN) pMOG[k].var.Blue += m_alpha*d; pMOG[k].var.Red = (std::max)(pMOG[k].var.Red,m_noise); pMOG[k].var.Green = (std::max)(pMOG[k].var.Green,m_noise); pMOG[k].var.Blue = (std::max)(pMOG[k].var.Blue,m_noise); } else pMOG[k].w = (1.0 - m_alpha)*pMOG[k].w; } } // no match found... create new one else { if(pK[n] < NUMBERGAUSSIANS) pK[n]++; kHit = pK[n] - 1; if(pK[n] == 1) pMOG[kHit].w = 1.0; else pMOG[kHit].w = LEARNINGRATEMOG; pMOG[kHit].mu.Red = srcR; pMOG[kHit].mu.Green = srcG; pMOG[kHit].mu.Blue = srcB; pMOG[kHit].var.Red = m_noise; pMOG[kHit].var.Green = m_noise; pMOG[kHit].var.Blue = m_noise; } // Normalize weights double wsum = 0.0; for(int k = 0; k < pK[n]; k++) wsum += pMOG[k].w; double wfactor = 1.0/wsum; for(int k = 0; k < pK[n]; k++) { pMOG[k].w *= wfactor; pMOG[k].sortKey = pMOG[k].w/sqrt(pMOG[k].var.Red+pMOG[k].var.Green+pMOG[k].var.Blue); } // Sort distributions for (int k = 0; k < kHit; k++) { if(pMOG[kHit].sortKey > pMOG[k].sortKey) { std::swap(pMOG[kHit],pMOG[k]); break; } } // Determine background distributions wsum = 0.0; for(int k = 0; k < pK[n]; k++) { wsum += pMOG[k].w; if(wsum > m_T) { kBG = k; break; } } if(kHit > kBG) prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255; else prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0; prgbBG[i][j].Red = (unsigned char)pMOG[0].mu.Red; prgbBG[i][j].Green = (unsigned char)pMOG[0].mu.Green; prgbBG[i][j].Blue = (unsigned char)pMOG[0].mu.Blue; pMOG += NUMBERGAUSSIANS; n++; } } return; }
void BGModelGauss::Update() { DBLRGB *pMu = m_pMu; DBLRGB *pVar = m_pVar; Image<BYTERGB> prgbSrc(m_SrcImage); Image<BYTERGB> prgbBG(m_BGImage); Image<BYTERGB> prgbFG(m_FGImage); for(int i = 0; i < m_height; i++) { for(int j = 0; j < m_width; j++) { double srcR = (double) prgbSrc[i][j].Red; double srcG = (double) prgbSrc[i][j].Green; double srcB = (double) prgbSrc[i][j].Blue; // Mahalanobis distance double dr = srcR - pMu->Red; double dg = srcG - pMu->Green; double db = srcB - pMu->Blue; double d2 = dr*dr/pVar->Red + dg*dg/pVar->Green + db*db/pVar->Blue; // Classify if(d2 < m_threshold) prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0; else prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255; // Update parameters if(dr*dr > DBL_MIN) pMu->Red += m_alpha*dr; if(dg*dg > DBL_MIN) pMu->Green += m_alpha*dg; if(db*db > DBL_MIN) pMu->Blue += m_alpha*db; double d; d = (srcR - pMu->Red)*(srcR - pMu->Red) - pVar->Red; if(d*d > DBL_MIN) pVar->Red += m_alpha*d; d = (srcG - pMu->Green)*(srcG - pMu->Green) - pVar->Green; if(d*d > DBL_MIN) pVar->Green += m_alpha*d; d = (srcB - pMu->Blue)*(srcB - pMu->Blue) - pVar->Blue; if(d*d > DBL_MIN) pVar->Blue += m_alpha*d; pVar->Red = (std::min)(pVar->Red,m_noise); pVar->Green = (std::min)(pVar->Green,m_noise); pVar->Blue = (std::min)(pVar->Blue,m_noise); // Set background prgbBG[i][j].Red = (unsigned char)pMu->Red; prgbBG[i][j].Green = (unsigned char)pMu->Green; prgbBG[i][j].Blue = (unsigned char)pMu->Blue; pMu++; pVar++; } } return; }
void BGModelFuzzySom::Update() { double alpha,a; double epsilon; // calibration phase if(m_K <= m_TSteps) { epsilon = m_epsilon1; alpha = (m_alpha1 - m_K * (m_alpha1 - m_alpha2) / m_TSteps); m_K++; } else // online phase { epsilon = m_epsilon2; alpha = m_alpha2; } Image<BYTERGB> prgbSrc(m_SrcImage); Image<BYTERGB> prgbBG(m_BGImage); Image<BYTERGB> prgbFG(m_FGImage); for(int j = 0; j < m_height; j++) { int jj = m_offset + j*(N + m_pad); for(int i = 0; i < m_width; i++) { int ii = m_offset + i*(M + m_pad); double srcR = (double)prgbSrc[j][i].Red; double srcG = (double)prgbSrc[j][i].Green; double srcB = (double)prgbSrc[j][i].Blue; // Find BMU double d2min = DBL_MAX; int iiHit = ii; int jjHit = jj; for(int l = 0; l < N; l++) { for(int k = 0; k < M; k++) { double dr = srcR - m_ppSOM[jj+l][ii+k].Red; double dg = srcG - m_ppSOM[jj+l][ii+k].Green; double db = srcB - m_ppSOM[jj+l][ii+k].Blue; double d2 = dr*dr + dg*dg + db*db; if(d2 < d2min) { d2min = d2; iiHit = ii + k; jjHit = jj + l; } } } double fuzzyBG = 1.0; if(d2min < epsilon) fuzzyBG = d2min/epsilon; // Update SOM double alphamax = alpha*exp(FUZZYEXP*fuzzyBG); for(int l = (jjHit - m_offset); l <= (jjHit + m_offset); l++) { for(int k = (iiHit - m_offset); k <= (iiHit + m_offset); k++) { a = alphamax * m_ppW[l - jjHit + m_offset][k - iiHit + m_offset]; // speed hack.. avoid very small increment values. abs() is sloooow. double d; d = srcR - m_ppSOM[l][k].Red; if(d*d > DBL_MIN) m_ppSOM[l][k].Red += a*d; d = srcG - m_ppSOM[l][k].Green; if(d*d > DBL_MIN) m_ppSOM[l][k].Green += a*d; d = srcB - m_ppSOM[l][k].Blue; if(d*d > DBL_MIN) m_ppSOM[l][k].Blue += a*d; } } if(fuzzyBG >= FUZZYTHRESH) { // Set foreground image prgbFG[j][i].Red = prgbFG[j][i].Green = prgbFG[j][i].Blue = 255; } else { // Set background image prgbBG[j][i].Red = m_ppSOM[jjHit][iiHit].Red; prgbBG[j][i].Green = m_ppSOM[jjHit][iiHit].Green; prgbBG[j][i].Blue = m_ppSOM[jjHit][iiHit].Blue; // Set foreground image prgbFG[j][i].Red = prgbFG[j][i].Green = prgbFG[j][i].Blue = 0; } } } return; }
void BGModelFuzzyGauss::Update() { DBLRGB *pMu = m_pMu; DBLRGB *pVar = m_pVar; Image<BYTERGB> prgbSrc(m_SrcImage); Image<BYTERGB> prgbBG(m_BGImage); Image<BYTERGB> prgbFG(m_FGImage); for(int i = 0; i < m_height; i++) { for(int j = 0; j < m_width; j++) { double srcR = (double) prgbSrc[i][j].Red; double srcG = (double) prgbSrc[i][j].Green; double srcB = (double) prgbSrc[i][j].Blue; // Fuzzy background subtraction (Mahalanobis distance) double dr = srcR - pMu->Red; double dg = srcG - pMu->Green; double db = srcB - pMu->Blue; double d2 = dr*dr/pVar->Red + dg*dg/pVar->Green + db*db/pVar->Blue; double fuzzyBG = 1.0; if(d2 < m_threshold) fuzzyBG = d2/m_threshold; // Fuzzy running average double alpha = m_alphamax*exp(FUZZYEXP*fuzzyBG); if(dr*dr > DBL_MIN) pMu->Red += alpha*dr; if(dg*dg > DBL_MIN) pMu->Green += alpha*dg; if(db*db > DBL_MIN) pMu->Blue += alpha*db; double d; d = (srcR - pMu->Red)*(srcR - pMu->Red) - pVar->Red; if(d*d > DBL_MIN) pVar->Red += alpha*d; d = (srcG - pMu->Green)*(srcG - pMu->Green) - pVar->Green; if(d*d > DBL_MIN) pVar->Green += alpha*d; d = (srcB - pMu->Blue)*(srcB - pMu->Blue) - pVar->Blue; if(d*d > DBL_MIN) pVar->Blue += alpha*d; pVar->Red = (std::max)(pVar->Red,m_noise); pVar->Green = (std::max)(pVar->Green,m_noise); pVar->Blue = (std::max)(pVar->Blue,m_noise); // Set foreground and background if(fuzzyBG >= m_threshBG) prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255; else prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0; prgbBG[i][j].Red = (unsigned char)pMu->Red; prgbBG[i][j].Green = (unsigned char)pMu->Green; prgbBG[i][j].Blue = (unsigned char)pMu->Blue; pMu++; pVar++; } } return; }