void RV02::Sobel (const channel8& sPic, channel8& GradientPic, channel8& DirectionPic){ const int PicSizeY = sPic.rows(); const int PicSizeX = sPic.columns(); int x, y; int gx, gy; for(x = 1; x < PicSizeX - 1; x++){ for(y = 1; y < PicSizeY - 1; y++){ // Gx berechnen gx = -sPic[y-1][x-1] + 0 + sPic[y-1][x+1] -2*sPic[y][x-1] + 0 + 2*sPic[y][x+1] -sPic[y+1][x-1] + 0 + sPic[y+1][x+1]; gx /= 4; // Gy berechnen gy = - sPic[y-1][x-1] - 2*sPic[y-1][x] - sPic[y-1][x+1] + 0 + 0 + 0 + sPic[y+1][x-1] + 2*sPic[y+1][x] + sPic[y+1][x+1]; gy /= 4; // Gradientenbetrag GradientPic[y][x] = sqrt(gx*gx + gy*gy); // Winkel: 180 <= angle < 540 double angle = atan2((double)gy,(double)gx)/PI*180+360.0; // Abbildung auf die Winkelbereiche int dir = ((int)(angle+22.5)%360)/45; DirectionPic[y][x] = dir; } } }
/* * compute the second and up iterations of a probability map * using the given aPriori probabilites per pixel. */ bool probabilityMap2D::computeMap(const channel8& src1, const channel8& src2, channel& aPrioriDest) const { point chnl1_size = src1.size(); point chnl2_size = src2.size(); // size of src1 equals src2 ? if ( (chnl1_size.x != chnl2_size.x) || (chnl1_size.y != chnl2_size.y) ) { setStatusString("probabilityMap2D: channels do not match"); return false; } else { int y; vector<channel8::value_type>::const_iterator srcIterator1, eit1; vector<channel8::value_type>::const_iterator srcIterator2, eit2; vector<channel::value_type>::iterator destIterator; const parameters& param = getParameters(); const thistogram<double>& objModel = param.getObjectColorModel(); const thistogram<double>& nonObjModel = param.getNonObjectColorModel(); float relObjProb; float relNonObjProb; ivector theBin(2); for (y=0;y<src1.rows();++y) { srcIterator1 = src1.getRow(y).begin(); eit1 = src1.getRow(y).end(); srcIterator2 = src2.getRow(y).begin(); eit2 = src2.getRow(y).end(); destIterator = aPrioriDest.getRow(y).begin(); while (srcIterator1 != eit1) { theBin[0] = lookupTable[0][*srcIterator1]; theBin[1] = lookupTable[1][*srcIterator2]; relObjProb = static_cast<float>(objModel.getProbability(theBin) * (*destIterator)); relNonObjProb = static_cast<float>(nonObjModel.getProbability(theBin)* (1.0f-(*destIterator))); // assume non-object if no entries are given if ((relObjProb == 0.0f) && (relNonObjProb == 0.0f)) { (*destIterator) = 0.0f; } else { // bayes (*destIterator) = relObjProb / (relObjProb + relNonObjProb); } srcIterator1++; srcIterator2++; destIterator++; } } } return true; }
void RV02::Median( const channel8& sPic, // source picture channel8& dPic, // destination picture const int MaskSizeX, // mask size in x-direction const int MaskSizeY // mask size in y-direction ) { const int PicSizeY = sPic.rows(); const int PicSizeX = sPic.columns(); const int maskWidth = (MaskSizeX % 2 == 0 ? MaskSizeX + 1 : MaskSizeX); const int maskHeight = (MaskSizeX % 2 == 0 ? MaskSizeY + 1 : MaskSizeY); const int maskSize = maskWidth * maskHeight; const int maskHalfWidth = maskWidth / 2; const int maskHalfHeight = maskHeight / 2; // Gesuchert Wert im akkumulierten Histogramm ubyte accuHistSearched = (maskSize + 1) / 2; ubyte histogram[256] = {0}; ubyte accHistogram[256] = {0}; int x, y, mx, my; for(y = maskHalfHeight; y < PicSizeY - maskHalfHeight; y++){ for(x = maskHalfWidth; x < PicSizeX - maskHalfWidth; x++){ // Alte Maskenhinstogrammwerte leeren std::fill(histogram, histogram + 256, 0); // Initialwerte ubyte minGrauwert = 255; ubyte maxGrauwert = 0; ubyte h = 0; // Maskenhistrogramm berechnen for(my = y - maskHalfHeight; my <= y + maskHalfHeight; my++){ for(mx = x - maskHalfWidth; mx <= x + maskHalfWidth; mx++){ histogram[sPic[my][mx]]++; h = sPic[my][mx]; if (h > maxGrauwert) { maxGrauwert = h; } if (h < minGrauwert){ minGrauwert = h; } } } // Akkumuliertes Histogrammwert berechnen // Der erste Index dessen Wert im akkumulierten Histogramm den accuHistValue ueberschreitet // ist der gesuchte Medianwert. int accuHistvalue = 0; for(int i = minGrauwert; i <= maxGrauwert; i++){ accuHistvalue += histogram[i]; if(accuHistvalue >= accuHistSearched) { dPic[y][x] = i; break; } } } } }
// return probability channel bool probabilityMap2D::apply(const channel8& src1, const channel8& src2, channel& dest) const { const parameters& param = getParameters(); point chnl1_size = src1.size(); point chnl2_size = src2.size(); // size of src1 equals src2 ? if ( (chnl1_size.x != chnl2_size.x) || (chnl1_size.y != chnl2_size.y) ) { setStatusString("probabilityMap2D: channels do not match"); return false; } // the color model MUST have 2 dimensions! if (probabilityHistogram.dimensions() == 2) { // resize probability channel dest.resize(src1.size()); ivector theBin(2); // compute first iteration int y; vector<channel8::value_type>::const_iterator srcIterator1, eit1; vector<channel8::value_type>::const_iterator srcIterator2, eit2; vector<channel::value_type>::iterator destIterator; for (y=0;y<src1.rows();++y) { srcIterator1 = src1.getRow(y).begin(); eit1 = src1.getRow(y).end(); srcIterator2 = src2.getRow(y).begin(); eit2 = src2.getRow(y).end(); destIterator = dest.getRow(y).begin(); while (srcIterator1 != eit1) { theBin[0] = lookupTable[0][*srcIterator1]; theBin[1] = lookupTable[1][*srcIterator2]; (*destIterator)=static_cast<float>(probabilityHistogram.at(theBin)); srcIterator1++; srcIterator2++; destIterator++; } } // compute all other iterations if (param.iterations > 1) { int i; if (param.gaussian) { gaussKernel2D<float> gk(param.windowSize,param.variance); convolution convolver; convolution::parameters convParam; convParam.boundaryType = lti::Mirror; convParam.setKernel(gk); convolver.setParameters(convParam); for (i=1;i<param.iterations;++i) { convolver.apply(dest); computeMap(src1,src2,dest); } } else { squareConvolution<float> convolver; squareConvolution<float>::parameters convParam; convParam.boundaryType = lti::Mirror; convParam.initSquare(param.windowSize); convolver.setParameters(convParam); for (i=1;i<param.iterations;++i) { convolver.apply(dest); computeMap(src1,src2,dest); } } } // of (param.iterations > 1) return true; } // of (probabilityHistogram.dimensions() == 2) setStatusString("probabilityMap2D: no models loaded"); return false; }
// On copy apply for type channel8! bool huMoments::apply(const channel8& src,dvector& dest, dvector& more) const { channel8::value_type val; dest.resize(NUM_FEAT,0,false,true); more.resize(MORE_FEAT,0,false,true); double m00=0.0; double cm11,cm20,cm02,cm30,cm03,cm12,cm21; cm11=cm20=cm02=cm30=cm03=cm12=cm21=0.0; double xcog, ycog; xcog=ycog=0.0; int r, rows=src.rows(); int c, cols=src.columns(); // compute simple moments and cog for (r=0; r<rows; r++) { for (c=0; c<cols; c++) { val = src.at(r,c); m00+=val; xcog+=c*val; ycog+=r*val; } } // end here, if no content if (m00==0) { return false; } // compute cog's more[huMoments::xcog]=xcog=xcog/m00; //xcog more[huMoments::ycog]=ycog=ycog/m00; //ycog // compute central moments for (r=0; r<rows; r++) { for (c=0; c<cols; c++) { val = src.at(r,c); double x_xcog = c-xcog; double y_ycog = r-ycog; cm11+=(x_xcog)*(y_ycog)*val; cm20+=(x_xcog)*(x_xcog)*val; cm02+=(y_ycog)*(y_ycog)*val; cm30+=(x_xcog)*(x_xcog)*(x_xcog)*val; cm03+=(y_ycog)*(y_ycog)*(y_ycog)*val; cm12+=(x_xcog)*(y_ycog)*(y_ycog)*val; cm21+=(x_xcog)*(x_xcog)*(y_ycog)*val; } } double m00pow2,m00pow2_5; m00pow2 = m00*m00; m00pow2_5 = pow(m00,2.5); // normalized central moments cm02 = cm02/m00pow2; cm03 = cm03/m00pow2_5; cm11 = cm11/m00pow2; cm12 = cm12/m00pow2_5; cm20 = cm20/m00pow2; cm21 = cm21/m00pow2_5; cm30 = cm30/m00pow2_5; // calculate moment invariants dest[huMoments::hu1] = cm20 + cm02; dest[huMoments::hu2] = pow((cm20 - cm02),2) + 4*pow(cm11,2); dest[huMoments::hu3] = pow((cm30 - 3*cm12),2) + pow((3*cm21 - cm03),2); dest[huMoments::hu4] = pow((cm30 + cm12),2) + pow((cm21 + cm03),2); dest[huMoments::hu5] = (cm30-3*cm12)*(cm30+cm12)*( pow((cm30+cm12),2) - 3*pow((cm21+cm03),2) ) + (3*cm21-cm03)*(cm21+cm03)*( 3*pow((cm30+cm12),2) - pow((cm21+cm03),2) ); dest[huMoments::hu6] = (cm20-cm02)*( pow((cm30+cm12),2) - pow((cm21+cm03),2) ) + 4*cm11*(cm30+cm12)*(cm21+cm03); dest[huMoments::hu7] = (3*cm21-cm03)*(cm30+cm12)*( pow((cm30+cm12),2) - 3*pow((cm21+cm03),2) ) - (cm30-3*cm12)*(cm21+cm03)*( 3*pow((cm30+cm12),2) - pow((cm21+cm03),2) ); double temp = sqrt( (cm20 - cm02)*(cm20 - cm02) + 4*cm11*cm11 ); more[huMoments::eigen1]=m00*0.5*((cm20+cm02) + temp); //eigen 1 more[huMoments::eigen2]=m00*0.5*((cm20+cm02) - temp); //eigen 2 more[huMoments::orientation]=0.5*atan2(2*cm11, cm20 - cm02); //orientation more[huMoments::m00]=m00; //m00 const parameters& param = getParameters(); if (param.scaling) { int i; for (i=0; i<dest.size();i++){ dest[i]=-logn(dest[i]); } } return true; }