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()); }
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++; } } }
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; }
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; } }
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; } }
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; }