Esempio n. 1
0
	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;
			}
		}
	}
Esempio n. 2
0
  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;
				}
			}
		}
	}
  }
  // 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;
  }