Example #1
0
int determine_optimal_threshold( CvHistogram* hist )
{
	// TO DO:  Given a 1-D CvHistogram you need to determine and return the optimal threshold value.

	// NOTES:  Assume there are 256 elements in the histogram.
	//         To get the histogram value at index i
	//            int histogram_value_at_i = ((int) *cvGetHistValue_1D(hist, i));

	int histogram_value_at[256];		// amount of pixel of every greyscale value 
	
	int temp_threshold_sum = 0;		//for calculating the initial_threshold
	int threshold_sum = 0;
	
	int initial_threshold = 0;			//T(1)
	int final_threshold = 0;			//T(n+1)

	int background = 0;				//summation of greyscale values of background
	int object = 0;					//summation of greyscale values of object

	int threshold_1 = 0;
	int threshold_2 = 0;

	//determine the first threshold. 
	//I initial the first threshold value by finding the value which divides the area of the curve into halves.
	for(int i = 0; i< 256; i++)
	{
		histogram_value_at[i] =  ((int) *cvGetHistValue_1D(hist, i));
		threshold_sum += histogram_value_at[i];
	}

	while(temp_threshold_sum < (threshold_sum/2))
	{
		temp_threshold_sum += histogram_value_at[initial_threshold++];
	}
	
	threshold_1 = initial_threshold;

	//optimal thresholding
	while(1)
	{
		object = sum_of_pixel_value(histogram_value_at, 0, threshold_1)/sum_of_pixel_number(histogram_value_at, 0, threshold_1);
		background = sum_of_pixel_value(histogram_value_at, threshold_1, 256)/sum_of_pixel_number(histogram_value_at, threshold_1, 256);

		threshold_2 = threshold_1;

		threshold_1 = (object + background)/2;
		
		if(abs(threshold_2 - threshold_1) < 1)		//T(n) = T(n+1) approximately
		{
			break;
		}

		//else continue doing the loop until T(n) = T(n+1)
	}

	return threshold_1;
	
}
void CvAdaptiveSkinDetector::Histogram::mergeWith(CvAdaptiveSkinDetector::Histogram *source, double weight)
{
	float myweight = (float)(1-weight);
	float maxVal1 = 0, maxVal2 = 0, *f1, *f2, ff1, ff2;

	cvGetMinMaxHistValue(source->fHistogram, NULL, &maxVal2);

	if (maxVal2 > 0 )
	{
		cvGetMinMaxHistValue(fHistogram, NULL, &maxVal1);
		if (maxVal1 <= 0)
		{
			for (int i = 0; i < HistogramSize; i++)
			{
				f1 = cvGetHistValue_1D(fHistogram, i);
				f2 = cvGetHistValue_1D(source->fHistogram, i);
				(*f1) = (*f2);
			}
		}
		else
		{
			for (int i = 0; i < HistogramSize; i++)
			{
				f1 = cvGetHistValue_1D(fHistogram, i);
				f2 = cvGetHistValue_1D(source->fHistogram, i);

				ff1 = ((*f1)/maxVal1)*myweight;
				if (ff1 < 0)
					ff1 = -ff1;

				ff2 = (float)(((*f2)/maxVal2)*weight);
				if (ff2 < 0)
					ff2 = -ff2;

				(*f1) = (ff1 + ff2);

			}
		}
	}
};
Example #3
0
float Histogram::getValue(int idx0, int idx1, int idx2) const
{
	switch (m_histogram->mat.dims) {
		case 1:
			return *cvGetHistValue_1D(m_histogram, idx0);
		case 2:
			return *cvGetHistValue_2D(m_histogram, idx0, idx1);
		case 3:
			return *cvGetHistValue_3D(m_histogram, idx0, idx1, idx2);
	}
	return NULL;
	
}
int CvAdaptiveSkinDetector::Histogram::findCoverageIndex(double surfaceToCover, int defaultValue)
{
	float s = 0;
	for (int i = 0; i < HistogramSize; i++)
	{
		s += *cvGetHistValue_1D( fHistogram, i );
		if (s >= surfaceToCover)
		{
			return i;
		}
	}
	return defaultValue;
};
Example #5
0
//--------------------------------------------------------------
void testApp::computeDepthHistogram (ofxCvGrayscaleImage depthImage) {
    // Compute the histogram of the depth-colored difference-from-background image.

    IplImage*  iplDepthImg = depthImage.getCvImage();
    cvCalcHist( &iplDepthImg, depthHistogram, 0, NULL );
    float *depthHistArr = cvGetHistValue_1D (depthHistogram, 0);

    int maxVal = 0;
    int startIndex = 1; // don't count black pixels.
    for (int i=startIndex; i<depthHistogramSize; i++) {
        if (depthHistArr[i] > maxVal) {
            maxVal = depthHistArr[i];
        }
    }

    for (int i=0; i<depthHistogramSize; i++) {
        depthHistogramData[i] = depthHistArr[i] / (float)maxVal;
    }
}
void CvAdaptiveSkinDetector::Histogram::findCurveThresholds(int &x1, int &x2, double percent)
{
	float sum = 0;

	for (int i = 0; i < HistogramSize; i++)
	{
		sum += *cvGetHistValue_1D( fHistogram, i );
	}

	x1 = findCoverageIndex(sum * percent, -1);
	x2 = findCoverageIndex(sum * (1-percent), -1);

	if (x1 == -1)
		x1 = GSD_HUE_LT;
	else
		x1 += GSD_HUE_LT;

	if (x2 == -1)
		x2 = GSD_HUE_UT;
	else
		x2 += GSD_HUE_LT;
};
void AdaptiveHistogramCamshift::AdaptHistogram(IplImage* hue, IplImage* mask, IplImage* out)
{
  // Prepare to analyze new track window
  const CvRect& updateHistRect = m_trackCompRect;

  // Now subdivide the track window and sum all pixels in each square
  // subdivision of size m_sBox using pixel values given by the
  // current hustogram.  When we are done, we will normalize the sum
  // from each subdivision and then be able to tell roughly how
  // similar each subregion is to the track histogram.

  // Make sure box size is greater than or equal to 2, and protect from
  // changes made in GUI
  const int sBox = std::max(m_sBox, 2);
  if (sBox != m_sBox)
  {
    m_sBox = sBox;
    cvSetTrackbarPos(ControlNames[ControlName_SBox], m_controlsGUIWndName.c_str(), sBox);
  }
  std::vector<float> subdivs;
  int numRows, numCols;
  SubdivideSumTrackWnd(sBox, &numRows, &numCols, &subdivs);

  // Check window is less than sBox in size.
  if (subdivs.empty())
  {
    return;
  }

  // Histogram for image subdivisions
  for (int i = 0; i < m_histDims; ++i)
  {
    float *bin = cvGetHistValue_1D(m_histTrackWnd, i);
    *bin = 0;
  }

  // Find the max vlaue of the subdivisions
  float maxVal = *std::max_element(subdivs.begin(), subdivs.end());;

  // DEBUG maxval
  //printf("maxVal: %f\n", maxVal);

  // Step through all subdivisions and weight them into a new histogram
  // if they are greater than minVal.  The weight function is r^2 where
  // r is the ratio of the subdivision value to the max subdivision
  // value.
  if (maxVal > 0)
  {
    float minVal = maxVal * 0.125f;
    float* subdivsCur = &subdivs[0];
    for (int i = 0; i < numRows; ++i)
    {
      for (int j = 0; j < numCols; ++j, ++subdivsCur)
      {
        // Create a box around this area
        CvPoint roiP1 = cvPoint(updateHistRect.x + sBox * j, updateHistRect.y + sBox * i);
        CvPoint roiP2 = cvPoint(roiP1.x + sBox, roiP1.y + sBox);

        if (*subdivsCur < minVal)
        {
          if(*subdivsCur > (minVal * 0.0625))
          {
            // Get ratio to max subdivision
            float ratioMaxSubdiv = *subdivsCur / maxVal;
            // Get color of surrounding box
            CvScalar boxColor = colors[GREEN];
            for (int colorInd = 0; colorInd < 3; ++colorInd)
            {
              boxColor.val[colorInd] *= ratioMaxSubdiv;
            }
            // Draw the box (darker green means less weight)
            if (out)
            {
              cvRectangle(out, roiP1, roiP2, boxColor, 1);
            }
          }
          else
          {
            // Draw a red box around this subdivision since it is not used
            if (out)
            {
              cvRectangle(out, roiP1, roiP2, colors[RED], 1 );
            }
          }
        }
        else
        {
          // Get ratio to max subdivision
          float ratioMaxSubdiv = *subdivsCur / maxVal;
          // Get weight into histogram of track window
          float weightVal = ratioMaxSubdiv * ratioMaxSubdiv;

          // DEBUG weights
          //printf("w %d: %f\t", j, weightVal);

          // Get color of surrounding box
          CvScalar boxColor = colors[GREEN];
          for (int colorInd = 0; colorInd < 3; ++colorInd)
          {
            boxColor.val[colorInd] *= ratioMaxSubdiv;
          }
          // Draw the box (darker green means less weight)
          if (out)
          {
            cvRectangle(out, roiP1, roiP2, boxColor, 1);
          }

          // Weight this subdivision into the histogram for the track window
          CvRect thisSubdivRect = cvRect(roiP1.x, roiP1.y, sBox, sBox);
          cvSetImageROI(hue, thisSubdivRect);
          cvSetImageROI(mask, thisSubdivRect);
          cvCalcHist(&hue, m_histSubdiv, 0, mask);
          cvResetImageROI(hue);
          cvResetImageROI(mask);

          // Weight this into the track window histogram
          for (int binNum = 0; binNum < m_histDims; ++binNum)
          {
            float* thisBin = cvGetHistValue_1D(m_histTrackWnd, binNum);
            *thisBin *= (1.0f - weightVal);
            *thisBin += static_cast<float>(cvGetReal1D(m_histSubdiv->bins, binNum)) * weightVal;
          }
        }
      }
      // DEBUG weights
      //printf("\n");
    }
    // DEBUG weights
    //printf("\n");
  }

  // DEBUG histograms
  //printf("Wnd BEFORE WT\n");
  //for( int i = 0; i < m_histDims; i++ ) {
  //  float *bin = cvGetHistValue_1D( m_histTrackWnd, i );
  //  printf("%2d: %3.1f  ", i, *bin);
  //  if( 0 == (i+1) % 8 ) {
  //    printf("\n");
  //  }
  //}


  // Now scale track window histogram to tracking histogram scale
  float trackWndHistMaxVal;
  cvGetMinMaxHistValue(m_histTrackWnd, 0, &trackWndHistMaxVal, 0, 0);
  cvConvertScale(m_histTrackWnd->bins, m_histTrackWnd->bins,
                 trackWndHistMaxVal ? HIST_SCALE / trackWndHistMaxVal : 0., 0);

  // Use aging to weight track window histogram into tracking histogram
  float averageBin = 0;
  for (int binNum = 0; binNum < m_histDims; ++binNum)
  {
    float* thisBin = cvGetHistValue_1D(m_hist, binNum);
    *thisBin *= (1.0f - (m_ageRatio / 100.0f));
    *thisBin += static_cast<float>(cvGetReal1D(m_histTrackWnd->bins, binNum)) *
                (m_ageRatio / 100.0f);
    averageBin += *thisBin;
  }
  averageBin /= m_histDims;

  // DEBUG average bin
  //printf("Avg bin: %f.\n", averageBin);

  // See if this histogram is dying
  //if( averageBin < SMALLEST_AVG_HIST_BIN ) {
  //    cvConvertScale( m_hist->bins, m_hist->bins, SMALLEST_AVG_HIST_BIN / averageBin, 0 );

  // DEBUG averageBin
  //printf("Hist saved for average bin: %f\n", averageBin);
  //}

  // DEBUG track hist
  //printf("Track\n");
  //for( int i = 0; i < m_histDims; i++ ) {
  //    float *bin = cvGetHistValue_1D( m_hist, i );
  //    printf("%2d: %3.1f  ", i, *bin);
  //    if( 0 == (i+1) % 8 ) {
  //        printf("\n");
  //    }
  //}
  //printf("\n");

  // Now compute histogram image
  cvZero(m_histImg);
  for (int i = 0; i < m_histDims; ++i)
  {
    const double raw = cvGetReal1D(m_hist->bins, i) * (m_histImg->height / HIST_SCALE);
    const int val = cvRound(raw);
    CvScalar color = hsv2rgb((i * m_histRanges[1]) / m_histDims);
    cvRectangle(m_histImg,
                cvPoint(i * m_binWidth, m_histImg->height),
                cvPoint((i + 1) * m_binWidth, m_histImg->height - val),
                color, -1, 8, 0);
  }

  // Show histogram
  if (m_showHistogram)
  {
    ShowHistogram();
  }
}