示例#1
0
void SmoothHeightMesh::MakeSmoothMesh()
{
	ScopedOnceTimer timer("SmoothHeightMesh::MakeSmoothMesh");

	// info:
	//   height-value array has size <maxx + 1> * <maxy + 1>
	//   and represents a grid of <maxx> cols by <maxy> rows
	//   maximum legal index is ((maxx + 1) * (maxy + 1)) - 1
	//
	//   row-width (number of height-value corners per row) is (maxx + 1)
	//   col-height (number of height-value corners per col) is (maxy + 1)
	//
	//   1st row has indices [maxx*(  0) + (  0), maxx*(1) + (  0)] inclusive
	//   2nd row has indices [maxx*(  1) + (  1), maxx*(2) + (  1)] inclusive
	//   3rd row has indices [maxx*(  2) + (  2), maxx*(3) + (  2)] inclusive
	//   ...
	//   Nth row has indices [maxx*(N-1) + (N-1), maxx*(N) + (N-1)] inclusive
	//
	const size_t size = (this->maxx + 1) * (this->maxy + 1);
	// use sliding window of maximums to reduce computational complexity
	const int intrad = smoothRadius / resolution;
	const int smoothrad = 3;

	assert(mesh.empty());
	mesh.resize(size);

	std::vector<float> colsMaxima(maxx + 1, -std::numeric_limits<float>::max());
	std::vector<int> maximaRows(maxx + 1, -1);
	std::vector<float> smoothed(size);

	FindMaximumColumnHeights(maxx, maxy, intrad, resolution, colsMaxima, maximaRows);

	for (int y = 0; y <= maxy; ++y) {
		AdvanceMaximaRows(y, maxx, resolution, colsMaxima, maximaRows);
		FindRadialMaximum(y, maxx, intrad, resolution, colsMaxima, mesh);
		FixRemainingMaxima(y, maxx, maxy, intrad, resolution, colsMaxima, maximaRows);

#ifdef _DEBUG
		CheckInvariants(y, maxx, maxy, intrad, resolution, colsMaxima, maximaRows);
#endif
	}

	// actually smooth with approximate Gaussian blur passes
	for (int numBlurs = 3; numBlurs > 0; --numBlurs) {
		BlurHorizontal(maxx, maxy, smoothrad, resolution, mesh, smoothed); mesh.swap(smoothed);
		BlurVertical(maxx, maxy, smoothrad, resolution, mesh, smoothed); mesh.swap(smoothed);
	}

	// `mesh` now contains the smoothed heightmap, save it in origMesh
	origMesh.resize(size);
	std::copy(mesh.begin(), mesh.end(), origMesh.begin());
}
示例#2
0
文件: MeshGroup.cpp 项目: sdp0et/gtp
void MeshGroup::smoothOperator( real AllVertex::* memberName )
{
  vector<real> smoothed( getTotalVertices(), 0.0 ) ;  // the smoothed quantity
  vector<int> numNeighbourCounts( getTotalVertices(), 0 ) ; // count of numneighbours for each vertex.
  
  int vID = 0 ;
  for( int meshNo = 0 ; meshNo < meshes.size() ; meshNo++ )
  {
    printf( "Smooth mesh %d / %d    \r", meshNo, meshes.size() ) ;
    // Different threads can take different verts to smooth.
    for( int vNo = 0 ; vNo < meshes[meshNo]->verts.size() ; vNo++ )
    {
      AllVertex *vertex = &meshes[meshNo]->verts[ vNo ] ;
      
      // we're at a vertex.  take the value of the vertex as the
      // initial value and increment neighbours
      smoothed[ vID ] = (vertex->*memberName) ;
      numNeighbourCounts[ vID ]++ ;
      
      for( int m = 0 ; m < meshes.size() ; m++ )
      {
        for( int j = 0 ; j < meshes[m]->verts.size() ; j++ )
        {
          AllVertex* other = &meshes[m]->verts[j];
          if( vertex != other && // skip yourself
              vertex->pos.Near( other->pos ) ) // we are near each other
          {
            // then we are neighbours
            smoothed[ vID ] += (other->*memberName) ;
            numNeighbourCounts[ vID ]++ ;
          }
        }
      }
      
      vID++;
    }
  }

  // Now write them.
  vID = 0 ;
  for( int meshNo = 0 ; meshNo < meshes.size() ; meshNo++ )
  {
    for( int vNo = 0 ; vNo < meshes[meshNo]->verts.size() ; vNo++ )
    {
      (meshes[meshNo]->verts[vNo].*memberName) =
        smoothed[ vID ]/numNeighbourCounts[ vID ] ;

      vID++;
    }
  }
}
示例#3
0
 std::vector<float> CosineHcdf::getRateOfChange(const Chromagram& ch, const Parameters& params){
   unsigned int hops = ch.getHops();
   unsigned int bins = ch.getBins();
   unsigned int gaussianSize = params.getHcdfGaussianSize();
   float gaussianSigma = params.getHcdfGaussianSigma();
   unsigned int padding = 0; // as opposed to gaussianSize/2
   std::vector<float> cosine(hops+padding);
   for (unsigned int hop = 0; hop < hops; hop++){
     float top = 0.0;
     float bottom = 0.0;
     for (unsigned int bin = 0; bin < bins; bin++){
       float mag = ch.getMagnitude(hop, bin);
       top += mag;
       bottom += pow(mag,2);
     }
     float cos;
     if(bottom > 0.0) // divzero
       cos = top / sqrt(bottom) * sqrt(bins * sqrt(2));
     else
       cos = 0.0;
     cosine[hop] = cos;
   }
   // gaussian
   std::vector<float> gaussian(gaussianSize);
   for (unsigned int i=0; i<gaussianSize; i++){
     gaussian[i] = exp(-1 * (pow(i - gaussianSize/2 , 2) / (2 * gaussianSigma * gaussianSigma)));
   }
   std::vector<float> smoothed(hops);
   for (unsigned int hop = padding; hop < cosine.size(); hop++){
     float conv = 0.0;
     for (unsigned int k=0; k<gaussianSize; k++){
       int frm = hop - (gaussianSize/2) + k;
       if(frm >= 0 && frm < (signed)cosine.size()){
         conv += cosine[frm] * gaussian[k];
       }
     }
     smoothed[hop-padding] = conv;
   }
   // rate of change of hcdf signal; look at all hops except first.
   std::vector<float> rateOfChange(hops);
   for (unsigned int hop=1; hop<hops; hop++){
     float change = (smoothed[hop] - smoothed[hop-1]) / 90.0;
     change = (change >= 0 ? change : change * -1.0);
     change = change / 0.16; // very cheeky magic number; for display purposes in KeyFinder GUI app
     rateOfChange[hop] = change;
   }
   // fudge first
   rateOfChange[0] = rateOfChange[1];
   return rateOfChange;
 }
示例#4
0
void MathUtilities::adaptiveThreshold(std::vector<double> &data)
{
    int sz = int(data.size());
    if (sz == 0) return;

    std::vector<double> smoothed(sz);
	
    int p_pre = 8;
    int p_post = 7;

    for (int i = 0; i < sz; ++i) {

        int first = std::max(0,      i - p_pre);
        int last  = std::min(sz - 1, i + p_post);

        smoothed[i] = mean(data, first, last - first + 1);
    }

    for (int i = 0; i < sz; i++) {
        data[i] -= smoothed[i];
        if (data[i] < 0.0) data[i] = 0.0;
    }
}
示例#5
0
  void PlateLines::processImage(Mat inputImage, vector<TextLine> textLines, float sensitivity)
  {
    if (this->debug)
      cout << "PlateLines findLines" << endl;

    timespec startTime;
    getTimeMonotonic(&startTime);


    // Ignore input images that are pure white or pure black
    Scalar avgPixelIntensity = mean(inputImage);
    if (avgPixelIntensity[0] >= 252)
      return;
    else if (avgPixelIntensity[0] <= 3)
      return;

    // Do a bilateral filter to clean the noise but keep edges sharp
    Mat smoothed(inputImage.size(), inputImage.type());
    adaptiveBilateralFilter(inputImage, smoothed, Size(3,3), 45, 45);


    int morph_elem  = 2;
    int morph_size = 2;
    Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );


    Mat edges(inputImage.size(), inputImage.type());
    Canny(smoothed, edges, 66, 133);

    // Create a mask that is dilated based on the detected characters


    Mat mask = Mat::zeros(inputImage.size(), CV_8U);

    for (unsigned int i = 0; i < textLines.size(); i++)
    {
      vector<vector<Point> > polygons;
      polygons.push_back(textLines[i].textArea);
      fillPoly(mask, polygons, Scalar(255,255,255));
    }



    dilate(mask, mask, getStructuringElement( 1, Size( 1 + 1, 2*1+1 ), Point( 1, 1 ) ));
    bitwise_not(mask, mask);

    // AND canny edges with the character mask
    bitwise_and(edges, mask, edges);


    vector<PlateLine> hlines = this->getLines(edges, sensitivity, false);
    vector<PlateLine> vlines = this->getLines(edges, sensitivity, true);
    for (unsigned int i = 0; i < hlines.size(); i++)
      this->horizontalLines.push_back(hlines[i]);
    for (unsigned int i = 0; i < vlines.size(); i++)
      this->verticalLines.push_back(vlines[i]);

    // if debug is enabled, draw the image
    if (this->debug)
    {
      Mat debugImgHoriz(edges.size(), edges.type());
      Mat debugImgVert(edges.size(), edges.type());
      edges.copyTo(debugImgHoriz);
      edges.copyTo(debugImgVert);
      cvtColor(debugImgHoriz,debugImgHoriz,CV_GRAY2BGR);
      cvtColor(debugImgVert,debugImgVert,CV_GRAY2BGR);

      for( size_t i = 0; i < this->horizontalLines.size(); i++ )
      {
        line( debugImgHoriz, this->horizontalLines[i].line.p1, this->horizontalLines[i].line.p2, Scalar(0,0,255), 1, CV_AA);
      }

      for( size_t i = 0; i < this->verticalLines.size(); i++ )
      {
        line( debugImgVert, this->verticalLines[i].line.p1, this->verticalLines[i].line.p2, Scalar(0,0,255), 1, CV_AA);
      }

      vector<Mat> images;
      images.push_back(debugImgHoriz);
      images.push_back(debugImgVert);

      Mat dashboard = drawImageDashboard(images, debugImgVert.type(), 1);
      displayImage(pipelineData->config, "Hough Lines", dashboard);
    }

    if (pipelineData->config->debugTiming)
    {
      timespec endTime;
      getTimeMonotonic(&endTime);
      cout << "Plate Lines Time: " << diffclock(startTime, endTime) << "ms." << endl;
    }

  }
示例#6
0
double MyTransforms::get_max_note_change(float *input, double period)
{
  //TODO
/*matlab code
l = length(s);
m = floor(l / 4); % m is the maximum size sub-window to use
% w is the sub-window size
if p < m
    w = p * floor(m / p);
else
    w = p;
end

n = -4:4;
ln = length(n);
left = cell(1, ln);
right = cell(1, ln);
left_pow = zeros(1, ln);
right_pow = zeros(1, ln);
pow = zeros(1, ln);
err = zeros(1, ln);

for i = 1:ln
    left{i} = s(1:(w-n(i))); % a smaller delay period has a larger window size, to ensure only the same data is used
    right{i} = s(1+p+n(i):w+p);
    left_pow(i) = sum(left{i}.^2);
    right_pow(i) = sum(right{i}.^2);
    err(i) = sum((left{i} - right{i}) .^ 2);
end
*/
  int i, j, j2;
  int max_subwindow = n / 4;
  int subwindow_size;
  if(period < 1.0) return 0.0; //period too small
  if(period > n/2) { printf("period = %lf\n", period); return 0.0; }
  int iPeriod = int(floor(period));
  if(period < double(max_subwindow)) subwindow_size = int(floor(period * (double(max_subwindow) / period)));
  else subwindow_size = int(floor(period));
  int num = n-subwindow_size-iPeriod;

  std::vector<int> offsets;
  for(j=-4; j<=4; j++) offsets.push_back(j); //do a total of 9 subwindows at once. 4 either side.
  int ln = offsets.size();

  std::vector<float> left(ln);
  std::vector<float> right(ln);
  std::vector<float> left_pow(ln);
  std::vector<float> right_pow(ln);
  std::vector<float> pow(ln);
  std::vector<float> err(ln);
  std::vector<float> result(ln);
  std::vector<float> unsmoothed(num);
  std::vector<float> smoothed(num);
  std::vector<float> smoothed_diff(num);
  //calc the values of pow and err for the first in each row.
  for(i=0; i<ln; i++) {
    left_pow[i] = right_pow[i] = pow[i] = err[i] = 0;
    for(j=0, j2=iPeriod+offsets[i]; j<subwindow_size-offsets[i]; j++, j2++) {
      left_pow[i] += sq(input[j]);
      right_pow[i] += sq(input[j2]);
      err[i] += sq(input[j] - input[j2]);
    }
  }
  //printf("subwindow_size=%d, num=%d, period=%lf\n", subwindow_size, num, period);
/*matlab code
for j = 1:(num-1)
    for i = 1:ln
        pow(i) = (left_pow(i) + right_pow(i));
        resulte(i, j) = err(i);
        resultp(i, j) = pow(i);
        result(i, j) = 1 - (err(i) / pow(i));

        %err = err - (s(j) - s(j+p)).^2 + (s(j+w) - s(j+w+p)).^2;
        err(i) = err(i) - ((s(j) - s(j+p+n(i))).^2) + (s(j+w-n(i)) - s(j+w+p)).^2;
        left_pow(i) = left_pow(i) - s(j).^2 + s(j+w-n(i)).^2;
        right_pow(i) = right_pow(i) - s(j+p+n(i)).^2 + s(j+p+w).^2;
    end
end

for i = 1:ln
    pow(i) = (left_pow(i) + right_pow(i));
    result(i, num) = 1 - (err(i) / pow(i));
end
*/
  //TODO: speed up this for loop
  for(j=0; j<num-1; j++) {
    for(i=0; i<ln; i++) {
      pow[i] = left_pow[i] + right_pow[i];
      result[i] = 1.0 - (err[i] / pow[i]);

      err[i] += -sq(input[j] - input[j+iPeriod+offsets[i]]) + sq(input[j+subwindow_size-offsets[i]] - input[j+subwindow_size+iPeriod]);
      left_pow[i] += -sq(input[j]) + sq(input[j+subwindow_size-offsets[i]]);
      right_pow[i] += -sq(input[j+iPeriod+offsets[i]]) + sq(input[j+iPeriod+subwindow_size]);
    }
/*matlab code
for j = 1:num
    [dud pos] = max(result(:,j));
    if pos > 1 && pos < ln
        [period(j) dummy] = parabolaPeak(result(pos-1, j), result(pos, j), result(pos+1, j), p+n(pos));
    else
        period(j) = p+n(pos);
    end
    period_int(j) = p+n(pos);
end*/
    int pos = int(std::max_element(result.begin(), result.begin()+ln) - result.begin());
    if(pos > 0 && pos < ln-1)
      unsmoothed[j] = double(iPeriod + offsets[pos]) + parabolaTurningPoint(result[pos-1], result[pos], result[pos+1]);
    else
      unsmoothed[j] = double(iPeriod + offsets[pos]);
  }
  fastSmooth->fast_smoothB(&(unsmoothed[0]), &(smoothed[0]), num-1);
  int max_pos = 0;
  for(j=0; j<num-2; j++) {
    smoothed_diff[j] = fabs(smoothed[j+1] - smoothed[j]);
    //printf("%f ", smoothed[j]);
    if(smoothed_diff[j] > smoothed_diff[max_pos]) max_pos = j;
  }
  //printf("\nsmooted_diff=%f\n", smoothed_diff[max_pos]);
  //return smoothed_diff[max_pos] / period * double(rate) * double(n) / 40000.0;
  double ret = smoothed_diff[max_pos] / period * double(rate) * double(subwindow_size) / 10000.0;
  //ret = (ret < 0.19) ? 0.0 : 1.0;
  return ret;
}
  void EGHTraceFitter::setInitialParameters_(FeatureFinderAlgorithmPickedHelperStructs::MassTraces& traces)
  {
    LOG_DEBUG << "EGHTraceFitter->setInitialParameters(...)" << std::endl;
    LOG_DEBUG << "Number of traces: " << traces.size() << std::endl;

    // aggregate data; some peaks (where intensity is zero) can be missing!
    // mapping: RT -> total intensity over all mass traces
    std::list<std::pair<double, double> > total_intensities;
    traces.computeIntensityProfile(total_intensities);

    // compute moving average for smoothing:
    const Size N = total_intensities.size();
    const Size LEN = 2;   // window size: 2 * LEN + 1
    std::vector<double> totals(N + 2 * LEN);   // pad with zeros at ends
    Int index = LEN;
    // LOG_DEBUG << "Summed intensities:\n";
    for (std::list<std::pair<double, double> >::iterator it =
           total_intensities.begin(); it != total_intensities.end(); ++it)
    {
      totals[index++] = it->second;
      // LOG_DEBUG << it->second << std::endl;
    }

    std::vector<double> smoothed(N);
    Size max_index = 0;   // index of max. smoothed intensity
    // LOG_DEBUG << "Smoothed intensities:\n";
    double sum = std::accumulate(&totals[LEN], &totals[2 * LEN], 0.0);
    for (Size i = 0; i < N; ++i)
    {
      sum += totals[i + 2 * LEN];
      smoothed[i] = sum / (2 * LEN + 1);
      sum -= totals[i];
      if (smoothed[i] > smoothed[max_index]) max_index = i;
      // LOG_DEBUG << smoothed[i] << std::endl;
    }
    LOG_DEBUG << "Maximum at index " << max_index << std::endl;
    height_ = smoothed[max_index] - traces.baseline;
    LOG_DEBUG << "height: " << height_ << std::endl;
    std::list<std::pair<double, double> >::iterator it = total_intensities.begin();
    std::advance(it, max_index);
    apex_rt_ = it->first;
    LOG_DEBUG << "apex_rt: " << apex_rt_ << std::endl;
    region_rt_span_ = (total_intensities.rbegin()->first -
                       total_intensities.begin()->first);
    LOG_DEBUG << "region_rt_span: " << region_rt_span_ << std::endl;

    // find RT values where intensity is at half-maximum:
    index = static_cast<Int>(max_index);
    while ((index > 0) && (smoothed[index] > height_ * 0.5))
      --index;
    double left_height = smoothed[index];
    it = total_intensities.begin();
    std::advance(it, index);
    double left_rt = it->first;
    LOG_DEBUG << "Left half-maximum at index " << index << ", RT " << left_rt
              << std::endl;
    index = static_cast<Int>(max_index);
    while ((index < Int(N - 1)) && (smoothed[index] > height_ * 0.5))
      ++index;
    double right_height = smoothed[index];
    it = total_intensities.end();
    std::advance(it, index - Int(N));
    double right_rt = it->first;
    LOG_DEBUG << "Right half-maximum at index " << index << ", RT "
              << right_rt << std::endl;

    double A = apex_rt_ - left_rt;
    double B = right_rt - apex_rt_;
    //LOG_DEBUG << "A: " << A << std::endl;
    //LOG_DEBUG << "B: " << B << std::endl;

    // compute estimates for tau / sigma based on A and B:
    double alpha = (left_height + right_height) * 0.5 / height_;   // ~0.5
    double log_alpha = log(alpha);

    tau_ = -1 / log_alpha * (B - A);
    //EGH function fails when tau==0
    if (tau_ == 0) tau_ = std::numeric_limits<double>::epsilon();

    LOG_DEBUG << "tau: " << tau_ << std::endl;
    sigma_ = sqrt(-0.5 / log_alpha * B * A);
    LOG_DEBUG << "sigma: " << sigma_ << std::endl;
  }
  void GaussTraceFitter::setInitialParameters_(FeatureFinderAlgorithmPickedHelperStructs::MassTraces& traces)
  {
    LOG_DEBUG << "GaussTraceFitter->setInitialParameters(...)" << std::endl;
    LOG_DEBUG << "Number of traces: " << traces.size() << std::endl;

    // aggregate data; some peaks (where intensity is zero) can be missing!
    // mapping: RT -> total intensity over all mass traces
    std::list<std::pair<double, double> > total_intensities;
    traces.computeIntensityProfile(total_intensities);

    const Size N = total_intensities.size();
    const Size LEN = 2; // window size: 2 * LEN + 1

    std::vector<double> totals(N + 2 * LEN); // pad with zeros at ends
    Int index = LEN;
    // LOG_DEBUG << "Summed intensities:\n";
    for (std::list<std::pair<double, double> >::iterator it =
           total_intensities.begin(); it != total_intensities.end(); ++it)
    {
      totals[index++] = it->second;
      // LOG_DEBUG << it->second << std::endl;
    }

    std::vector<double> smoothed(N);
    Size max_index = 0; // index of max. smoothed intensity
    if (N <= LEN + 1) // not enough distinct x values for smoothing
    {
      // throw Exception::UnableToFit(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "UnableToFit-MovingAverage", "Too few time points for smoothing with window size " + String(2 * LEN + 1));
      for (Size i = 0; i < N; ++i)
      {
        smoothed[i] = totals[i + LEN];
        if (smoothed[i] > smoothed[max_index]) max_index = i;
      }
    }
    else // compute moving average for smoothing
    {
      // LOG_DEBUG << "Smoothed intensities:\n";
      double sum = std::accumulate(&totals[LEN], &totals[2 * LEN], 0.0);
      for (Size i = 0; i < N; ++i)
      {
        sum += totals[i + 2 * LEN];
        smoothed[i] = sum / (2 * LEN + 1);
        sum -= totals[i];
        if (smoothed[i] > smoothed[max_index]) max_index = i;
        // LOG_DEBUG << smoothed[i] << std::endl;
      }
    }
    LOG_DEBUG << "Maximum at index " << max_index << std::endl;
    height_ = smoothed[max_index] - traces.baseline;
    LOG_DEBUG << "height: " << height_ << std::endl;
    std::list<std::pair<double, double> >::iterator it = total_intensities.begin();
    std::advance(it, max_index);
    x0_ = it->first;
    LOG_DEBUG << "x0: " << x0_ << std::endl;
    region_rt_span_ = (total_intensities.rbegin()->first -
                       total_intensities.begin()->first);
    LOG_DEBUG << "region_rt_span: " << region_rt_span_ << std::endl;

    // find RT values where intensity is at half-maximum:
    index = static_cast<Int>(max_index);
    while ((index > 0) && (smoothed[index] > height_ * 0.5))
      --index;
    double left_height = smoothed[index];
    it = total_intensities.begin();
    std::advance(it, index);
    double left_rt = it->first;
    LOG_DEBUG << "Left half-maximum at index " << index << ", RT " << left_rt
              << std::endl;
    index = static_cast<Int>(max_index);
    while ((index < Int(N - 1)) && (smoothed[index] > height_ * 0.5))
      ++index;
    double right_height = smoothed[index];
    it = total_intensities.end();
    std::advance(it, index - Int(N));
    double right_rt = it->first;
    LOG_DEBUG << "Right half-maximum at index " << index << ", RT "
              << right_rt << std::endl;

    double delta_x = right_rt - left_rt;
    double alpha = (left_height + right_height) * 0.5 / height_; // ~0.5
    if (alpha >= 1) sigma_ = 1.0; // degenerate case, all values are the same
    else sigma_ = delta_x * 0.5 / sqrt(-2.0 * log(alpha));
    LOG_DEBUG << "sigma: " << sigma_ << std::endl;
  }