void interpolateDistance(size_t x1, size_t y1, size_t x2, size_t y2, const unsigned char* I) { int i1 = iPos(x1, y1); if ((I[iPos(x2, y2)] > 127) != (I[i1] > 127)) { //double interpDist = std::abs((128.0 - I[i1]) / (double(I[iPos(x2, y2)]) - I[i1])); d[i1] = 1;//std::min(d[i1], interpDist); p[i1][0] = x2; p[i1][1] = y2; } }
inline void check(int x, int y, double delta, size_t i2) { int i1 = iPos(x,y); if (d[i1] + delta < d[i2]) { p[i2] = p[i1]; const double deltaX = (p[i1][0] - x); const double deltaY = (p[i1][1] - y); d[i2] = std::sqrt(deltaX*deltaX + deltaY*deltaY); } }
SignedDistanceTransform(unsigned char* I, size_t width, size_t height): _width(width), _height(height) { //The border of the image must be 0 for (size_t x(0); x < _width; ++x) { I[iPos(x, 0)] = 0; I[iPos(x, _height - 1)] = 0; } for (size_t y(0); y < _height; ++y) { I[iPos(0, y)] = 0; I[iPos(_width - 1, y)] = 0; } double floatInf = std::numeric_limits<float>::max() / 2; p.resize(_width * _height); d.resize(_width * _height, floatInf); //Iterate over the image's non-border pixels, finding color //edge pixels. for (size_t y(1); y < _height - 1; ++y) for (size_t x(1); x < _width - 1; ++x) { interpolateDistance(x, y, x - 1, y, I); interpolateDistance(x, y, x + 1, y, I); interpolateDistance(x, y, x, y - 1, I); interpolateDistance(x, y, x, y + 1, I); } //First "forward" pass for (int y(1); y < int(_height) - 1; ++y) for (int x(1); x < int(_width) - 1; ++x) { int i2 = iPos(x,y); check(x-1,y-1,std::sqrt(2), i2); check(x,y-1,1, i2); check(x+1,y-1,std::sqrt(2), i2); check(x-1,y,1, i2); } //Second "reverse" pass for (int y(_height - 2); y > 0; --y) for (int x(_width - 2); x > 0; --x) { size_t i2 = iPos(x,y); check(x+1,y,1, i2); check(x-1,y+1,std::sqrt(2), i2); check(x,y+1,1, i2); check(x+1,y+1,std::sqrt(2), i2); } //Transform the output to a scaled range for (size_t x(0); x < _width; ++x) for (size_t y(0); y < _height; ++y) { size_t i = iPos(x,y); double locd = (I[i] > 127) ? d[i] : -d[i]; I[i] = std::min(255.0, std::max(0.0, 128 + locd)); } }
/** \brief Replace all occurrences of a substring with another string. \param strFind The string that shall be replaced. \param strReplaceWith The string that should be inserted instead of strFind */ void ParserError::ReplaceSubString( string_type &strSource, const string_type &strFind, const string_type &strReplaceWith) { string_type strResult; string_type::size_type iPos(0), iNext(0); for(;;) { iNext = strSource.find(strFind, iPos); strResult.append(strSource, iPos, iNext-iPos); if( iNext==string_type::npos ) break; strResult.append(strReplaceWith); iPos = iNext + strFind.length(); } strSource.swap(strResult); }