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;
			}
		}
	}
  // On copy apply for type channel8!
  bool harrisCorners::apply(const channel8& src,channel8& dest) const {
    pointList pts;
    if (apply(src,pts)) {
      const parameters& par = getParameters();
      pointList::iterator it;
      dest.resize(src.size(),par.noCornerValue,false,true);
      for (it=pts.begin();it!=pts.end();++it) {
        dest.at(*it)=par.cornerValue;
      }
      return true;
    }

    return false;
  };
  // merge 8-bit channels
  bool mergeOCPToImage::apply(const channel8& c1,
                              const channel8& c2,
                              const channel8& c3,
                              image& img) const {

    point p;              // coordinates
    float r,g,b;          // unnormed RGB channels
    float RG, BY, WB;     // opponent colour channels
    
    if ((c1.size() != c2.size()) || (c1.size() != c3.size())) {
      setStatusString("sizes of channels do not match");
      return false;
    }
    
    img.resize(c1.size(),rgbPixel(),false,false);

    for (p.y=0;p.y<img.rows();p.y++) {
      for (p.x=0;p.x<img.columns();p.x++) {

	RG = static_cast<float>(c1.at(p)) - 127.5f;
	BY = static_cast<float>(c2.at(p)) - 127.5f;
	WB = static_cast<float>(c3.at(p)) - 127.5f;
        
        b = BY*0.66666666666667f;
        //
	r = WB + RG - b;
	g = WB - RG - b;
	b = WB + BY*1.3333333333333f;

	// truncate r,g and b if the value is not in intervall [0..1]
	// can happen due to rounding errors in split operation
	if (r<0.0f) {
          r=0.0f;
        } else if (r>255.0f) {
          r=255.0f;
        }

	if (g<0.0f) {
          g=0.0f;
        } else if (g>255.0f) {
          g=255.0f;
        }

	if (b<0.0f) {
          b=0.0f;
        } else if (b>255.0f) {
          b=255.0f;
        }

	img.at(p).set(static_cast<ubyte>(r),
                      static_cast<ubyte>(g),
                      static_cast<ubyte>(b),
                      0);
      }
    }

    return true;
  };
 bool kNearestNeighFilter::apply(const channel8& src,channel8& dest) {
   imatrix tmpSrc,tmpDest;
   tmpSrc.castFrom(src);
   apply(tmpSrc,tmpDest);
   dest.castFrom(tmpDest);
   return true;
 }
  /*
   * 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;
  }
 // On copy apply for type channel8!
 bool distanceTransform::apply(const channel8& src,channel8& dest) const {
   channel tmp;
   tmp.castFrom(static_cast<matrix<ubyte> >(src));
   if (apply(tmp)) {
     dest.castFrom(static_cast<matrix<float> >(tmp));
     return true;
   }
   return false;
 };
  // split image into 8-bit channels
  // N.B.: when casting the transformation result to unsigned shorts
  // (8-bit channel), major rounding errors will occur.
  // As a result, the merging operation might
  // produce negative values or values > 1,  which are truncated subsequently.
  // When accurate X, Y and Z channels are required, prefer float channels!
  bool splitImageToxyY::apply(const image& img,
                              channel8& c1,
                              channel8& c2,
                              channel8& c3) const {
    point p;       // coordinates
    rgbPixel pix;          // single Pixel Element in RGB-values...
    float Y;               // channels
    float X, XYZ;          // help variables

    // make the channels size of source image...
    c1.resize(img.rows(),img.columns(),0,false,false);
    c2.resize(img.rows(),img.columns(),0,false,false);
    c3.resize(img.rows(),img.columns(),0,false,false);

    for (p.y=0;p.y<img.rows();p.y++)
      for (p.x=0;p.x<img.columns();p.x++) {
        // take pixel at position p
        pix = img.at(p);

  // see Gonzales & Woods for explanation of magic numbers
        X   = (((float)(pix.getRed())) *0.412453f +
               ((float)(pix.getGreen())) *0.357580f +
               ((float)(pix.getBlue())) *0.180423f)/255.0f;   // x
        Y   = (((float)(pix.getRed())) *0.212671f +
               ((float)(pix.getGreen())) *0.715160f +
               ((float)(pix.getBlue())) *0.072169f)/255.0f;   // y
        XYZ = (((float)(pix.getRed())) *0.644458f +
               ((float)(pix.getGreen())) *1.191933f +
               ((float)(pix.getBlue())) *1.202819f)/255.0f;   // Y

        if (XYZ>0.0f) {
          c1.at(p) = (ubyte)(X/XYZ*255.0f);  // x
          c2.at(p) = (ubyte)(Y/XYZ*255.0f);  // y
        }
        else {
          c1.at(p) = 0;   // x
          c2.at(p) = 0;   // y
        }

        c3.at(p) = (ubyte)(Y*255.0f);     // Y
      } // loop
    return true;
  }
 // set the mask to use
 void correlation::parameters::setMask(const channel8& aMask) {
   delete mask;
   mask=dynamic_cast<channel8*>(aMask.clone());
 }
Esempio n. 9
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;
				}
			}
		}
	}
  }
  // 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;
  }
Esempio n. 11
0
  // Quantization takes place here!
  bool medianCut::performQuantization(const image& src,
                                      image& dest,
                                      channel8& mask,
                                      palette &thePalette) const {

    // parameters and const variables
    const parameters& param = getParameters();
    const int imageRows=src.rows();          // number of rows in src
    const int imageCols=src.columns();       // number of columns in src

    // resize destination containers
    dest.resize(imageRows,imageCols,rgbPixel(),false,false);
    mask.resize(imageRows,imageCols,ubyte(),false,false);

    // Variables
    int row,col;            // row, column counters
    int r,g,b;              // red,green,blue
    ivector iVec(3);        // int-vector

    std::list<boxInfo> theLeaves; // list of leaves (tree without root
                                  // and nodes)
    std::list<boxInfo>::iterator  splitPos;   // position to split
    std::list<boxInfo>::iterator  iter;       // iterator for theLeaves

    // create histogram with desired pre-quantization dimensions from src
    histogram theHist(3,param.preQuant);

    const float factor = param.preQuant/256.0f;

    for (row = 0 ; row < imageRows ; row++) {
      for (col = 0 ; col < imageCols ; col++) {

        r = static_cast<int>(src.at( row,col ).getRed()   * factor);
        g = static_cast<int>(src.at( row,col ).getGreen() * factor);
        b = static_cast<int>(src.at( row,col ).getBlue()  * factor);
        
        // insert point with quantized color
        dest.at(row,col).set((r*256+128)/param.preQuant,
                             (g*256+128)/param.preQuant,
                             (b*256+128)/param.preQuant,0); 

        iVec[0] = r;
        iVec[1] = g;
        iVec[2] = b;

        theHist.put(iVec);
      }
    }

    // initialization of first box of list (the whole histogram)
    boxInfo theBox(rgbPixel(0,0,0),
                   rgbPixel(param.preQuant-1,
                            param.preQuant-1,
                            param.preQuant-1));

    computeBoxInfo(theHist,theBox);

    // return, if desired number of colors smaller than colors in
    // pre-quantized image
    if (theBox.colors < param.numberOfColors) {

      thePalette.resize(theBox.colors,rgbPixel(),false,false);

      // prepare palette     
      int i = 0;
      for (r=0;r<param.preQuant;++r) {
        for (g=0;g<param.preQuant;++g) {
          for (b=0;b<param.preQuant;++b) {
            iVec[0] = r;
            iVec[1] = g;
            iVec[2] = b;
            if (theHist.at(iVec) > 0) {
              thePalette.at(i).set((r*256+128)/param.preQuant,
                                   (g*256+128)/param.preQuant,
                                   (b*256+128)/param.preQuant);
            }
          }
        }
      }

      // use the palette to generate the corresponding channel
      usePalette colorizer;
      colorizer.apply(dest,thePalette,mask);
      
      return true;
    }

    // Push first box into List
    theLeaves.push_back(theBox);

    // MAIN LOOP (do this until you have enough leaves (count), or no
    // splittable boxes (entries))
    int count, entries=1;  // auxiliary variables for the main loop
    for (count=1; (count<param.numberOfColors) && (entries!=0); count++) {

      // find box with largest number of entries from list
      entries = 0;
      for (iter = theLeaves.begin() ; iter != theLeaves.end() ; iter++) {
        if ( (*iter).colorFrequency > entries ) {
          // Avoid choosing single colors, i.e. unsplittable boxes
          if (  ((*iter).max.getRed()   > (*iter).min.getRed())   ||
                ((*iter).max.getGreen() > (*iter).min.getGreen()) ||
                ((*iter).max.getBlue()  > (*iter).min.getBlue()) ) {
            entries   = (*iter).colorFrequency;
            splitPos  = iter;
          }
        }
      }

      // A splittable box was found.
      // The iterator "splitPos" indicates its position in the List
      if (entries >0) {
        // Determine next axis to split (largest variance) and box dimensions
        int splitAxis;  // split axis indicator
        if ( ((*splitPos).var[0] >= (*splitPos).var[1]) &&
             ((*splitPos).var[0] >= (*splitPos).var[2]) ) {
          splitAxis = 0;  // red axis
        }
        else if ( (*splitPos).var[1] >= (*splitPos).var[2] ) {
          splitAxis = 1;  // green axis
        }
        else {
          splitAxis = 2;  // blue axis
        }

        int rMax  = ((*splitPos).max.getRed());
        int rMin  = ((*splitPos).min.getRed());
        int gMax  = ((*splitPos).max.getGreen());
        int gMin  = ((*splitPos).min.getGreen());
        int bMax  = ((*splitPos).max.getBlue());
        int bMin  = ((*splitPos).min.getBlue());

        // pass through box along the axis to split
        bool found;             // becomes true when split plane is found
        int nrOfCols=0;         // counter: number of colors of box
        int prevNrOfCols=0;     // forerunner of nrOfCols
        rgbPixel lower1;   // lower pixel from box 1
        rgbPixel upper1;   // upper pixel from box 1
        rgbPixel lower2;   // lower pixel from box 2
        rgbPixel upper2;   // upper pixel from box 2

        switch (splitAxis) {
          case 0: // red axis
            nrOfCols = 0;
            for (r = rMin , found = false ; (!found) && (r<=rMax) ; r++) {
              prevNrOfCols = nrOfCols;
              for (g = gMin ; g <= gMax ; g++) {
                for (b=bMin;b<=bMax;b++) {
                  iVec[0] = r;
                  iVec[1] = g;
                  iVec[2] = b;
                  if (theHist.at(iVec) > 0.0) {
                    nrOfCols += static_cast<long int>(theHist.at(iVec));
                  }
                }
              }
              if ( nrOfCols >= (*splitPos).colorFrequency/2 ) {
                found=true;
              }
            }
            if (fabs(prevNrOfCols -
                     static_cast<float>((*splitPos).colorFrequency)/2) <
                fabs(nrOfCols     -
                     static_cast<float>((*splitPos).colorFrequency)/2)) {
                r--;
                nrOfCols = prevNrOfCols;
            }
            // first box
            lower1.setRed(rMin);  lower1.setGreen(gMin);  lower1.setBlue(bMin);
            upper1.setRed(r-1);   upper1.setGreen(gMax);  upper1.setBlue(bMax);
            // second box
            lower2.setRed(r);     lower2.setGreen(gMin);  lower2.setBlue(bMin);
            upper2.setRed(rMax);  upper2.setGreen(gMax);  upper2.setBlue(bMax);
            break;

          case 1: // g axis
            nrOfCols = 0;
            for (g = gMin , found = false ; (!found) && (g<=gMax) ; g++) {
              prevNrOfCols = nrOfCols;
              for (r = rMin ; r <= rMax ; r++) {
                for (b = bMin ; b <= bMax ; b++) {
                  iVec[0] = r;
                  iVec[1] = g;
                  iVec[2] = b;
                  if (theHist.at(iVec) > 0.0) {
                    nrOfCols += static_cast<long int>(theHist.at(iVec));
                  }
                }
              }
              if ( nrOfCols >= (*splitPos).colorFrequency/2 ) {
                found=true;
              }
            }
            if (fabs(prevNrOfCols -
                     static_cast<float>((*splitPos).colorFrequency)/2) <
                fabs(nrOfCols     -
                     static_cast<float>((*splitPos).colorFrequency)/2)) {
                g--;
                nrOfCols = prevNrOfCols;
            }
            // first box
            lower1.setRed(rMin);  lower1.setGreen(gMin);  lower1.setBlue(bMin);
            upper1.setRed(rMax);  upper1.setGreen(g-1);   upper1.setBlue(bMax);
            // second box
            lower2.setRed(rMin);  lower2.setGreen(g);     lower2.setBlue(bMin);
            upper2.setRed(rMax);  upper2.setGreen(gMax);  upper2.setBlue(bMax);
            break;

          case 2: // b axis
            nrOfCols = 0;
            for (b = bMin , found = false ; (!found) && (b<=bMax) ; b++) {
              prevNrOfCols = nrOfCols;
              for (r = rMin ; r <= rMax ; r++) {
                for (g = gMin ; g <= gMax ; g++) {
                  iVec[0] = r;
                  iVec[1] = g;
                  iVec[2] = b;
                  if (theHist.at(iVec) > 0.0) {
                    nrOfCols += static_cast<long int>(theHist.at(iVec));
                  }
                }
              }
              if ( nrOfCols >= (*splitPos).colorFrequency/2 ) {
                found=true;
              }
            }
            if (fabs(prevNrOfCols -
                     static_cast<float>((*splitPos).colorFrequency)/2) <
                fabs(nrOfCols     -
                     static_cast<float>((*splitPos).colorFrequency)/2)) {
                b--;
                nrOfCols = prevNrOfCols;
            }
            // first box
            lower1.setRed(rMin); lower1.setGreen(gMin); lower1.setBlue(bMin);
            upper1.setRed(rMax); upper1.setGreen(gMax); upper1.setBlue(b-1);
            // second box
            lower2.setRed(rMin); lower2.setGreen(gMin); lower2.setBlue(b);
            upper2.setRed(rMax); upper2.setGreen(gMax); upper2.setBlue(bMax);
            break;
          default:
            break;
        } // end of switch

        // compute box info of new boxes and
        // append both at the end of list
        theBox.min = lower1;
        theBox.max = upper1;
        computeBoxInfo(theHist,theBox);
        theLeaves.push_back(theBox);

        theBox.min = lower2;
        theBox.max = upper2;
        computeBoxInfo(theHist,theBox);
        theLeaves.push_back(theBox);

        // delete splited box from list
        theLeaves.erase(splitPos);
      }

    } // end of for (MAIN LOOP)

    // compute block histogram and respective color palette
    thePalette.resize(theLeaves.size());
    int i;
    for (iter = theLeaves.begin() , i=0 ;
         iter != theLeaves.end() ;
         iter++ , i++) {
      // misuse histogram as a look-up-table
      for (r = (*iter).min.getRed(); r <= (*iter).max.getRed(); r++) {
        for (g = (*iter).min.getGreen(); g <= (*iter).max.getGreen(); g++) {
          for (b = (*iter).min.getBlue(); b <= (*iter).max.getBlue(); b++) {
            iVec[0] = r;
            iVec[1] = g;
            iVec[2] = b;
            theHist.at(iVec) = i; // insert palette-index (refers to
                                  // color in palette)
          }
        }
      }

      // create palette
      r = (static_cast<int>((*iter).mean[0]*factor)*256+128)/param.preQuant;
      g = (static_cast<int>((*iter).mean[1]*factor)*256+128)/param.preQuant;
      b = (static_cast<int>((*iter).mean[2]*factor)*256+128)/param.preQuant;
      thePalette[i].set(r,g,b,0);  // insert color
    }

    // create new image with palette and theHist
    dest.resize(imageRows,imageCols);
    mask.resize(imageRows,imageCols,0,false,true);

    // <= 256 colors? then also fill the mask
    if (thePalette.size() <= 256) {
      for (row = 0 ; row < imageRows ; row++) {
        for (col = 0 ; col < imageCols ; col++) {
          iVec[0] = static_cast<int>(src.at( row,col ).getRed()   * factor);
          iVec[1] = static_cast<int>(src.at( row,col ).getGreen() * factor);
          iVec[2] = static_cast<int>(src.at( row,col ).getBlue()  * factor);

          i = static_cast<int>(theHist.at( iVec ));

          dest.at(row,col) = thePalette[i];// insert point with quantized color
          mask.at(row,col) = i;     // insert palette index of quantized color
        }
      }
    }
    else {
      for (row = 0 ; row < imageRows ; row++) {
        for (col = 0 ; col < imageCols ; col++) {
          iVec[0] = static_cast<int>(src.at( row,col ).getRed()   * factor);
          iVec[1] = static_cast<int>(src.at( row,col ).getGreen() * factor);
          iVec[2] = static_cast<int>(src.at( row,col ).getBlue()  * factor);

          i = static_cast<int>(theHist.at( iVec ));

          r = thePalette[i].getRed();
          g = thePalette[i].getGreen();
          b = thePalette[i].getBlue();

          dest.at(row,col).set(r,g,b,0); // insert point with quantized color
        }
      }
    }

    return true;
  }
Esempio n. 12
0
  // 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;
  }