83 {
m_cd.resize(w * h, 0); }
138 int shift = (
m_h - 1) *
m_w;
139 for (
int i = 0; i <
m_w; i++) {
140 in[i] = in[i + shift] = borderval;
145 for (
int j = 0; j <
m_h; j++) {
146 in[j *
m_w] = in[(j + 1) *
m_w - 1] = borderval;
157 for (
int x = 0; x <
m_w - 1; x++) {
158 for (
int y = 0; y <
m_h - 1; y++) {
171 m_cd[
ixy(x, y)] = b0 | b1 | b2 | b3;
212 std::vector<double> subContourX(
length), subContourY(
length);
213 std::vector<int> subContourIndexes(
length);
215 for (
size_t i = 0; i <
length; ++i) {
228 for (
int i =
static_cast<int>(length0); i >= 0;
242 for (
size_t i = 0; i <
length; ++i) {
272 static const int TRAVERSAL[4] = {
BOTTOM,
LEFT,
275 static const int DISAMBIGUATION_UP[4] = {
277 static const int DISAMBIGUATION_DOWN[4] = {
293 int altToEdge =
NONE;
294 int altStartIndex = 0;
295 bool alternatePath =
false;
297 const int maxCellIndex =
299 while (cellIndex < maxCellIndex) {
301 int fromEdge = (toEdge ==
NONE ?
NONE : TRAVERSAL[toEdge]);
305 if (fromEdge ==
NONE) altToEdge =
NONE;
307 int currentCellIndex = -1;
310 if (fromEdge ==
NONE) {
312 if (altToEdge !=
NONE && !alternatePath) {
318 alternatePath =
true;
326 alternatePath =
false;
329 while (++cellIndex < maxCellIndex &&
333 if (cellIndex == maxCellIndex)
break;
334 currentCellIndex = cellIndex;
336 x = currentCellIndex %
m_w;
337 y = currentCellIndex /
m_w;
341 if (x < 0 || x >=
m_w - 1 || y < 0 || y >=
m_h - 1) {
343 if (fromEdge !=
NONE) {
348 }
else if (fromEdge !=
NONE) {
351 currentCellIndex =
ixy(x, y);
354 assert(currentCellIndex >= 0);
355 int& currentCode =
m_cd[currentCellIndex];
356 switch (currentCode) {
360 if (fromEdge !=
NONE) {
377 if (fromEdge ==
NONE) {
394 altStartIndex = currentCellIndex;
421 if (fromEdge !=
NONE) {
429 assert(!alternatePath);
439 (in[
ixy(x + 0, y + 0)] + in[
ixy(x + 1, y + 0)] +
440 in[
ixy(x + 0, y + 1)] +
441 in[
ixy(x + 1, y + 1)]) /
450 if (fromEdge ==
NONE) {
456 toEdge = DISAMBIGUATION_DOWN[fromEdge];
459 if (fromEdge ==
NONE) {
474 toEdge = DISAMBIGUATION_UP[fromEdge];
490 toEdge = (fromEdge ==
NONE || fromEdge ==
LEFT ?
TOP
501 assert(currentCode > 0 &&
503 if (fromEdge !=
NONE) {
510 assert(!alternatePath);
524 assert(toEdge !=
NONE);
526 if (fromEdge ==
NONE) {
537 double x2 = 0.0, y2 = 0.0;
541 LERP(in[
ixy(x + 0, y + 0)], in[
ixy(x + 1, y + 0)]);
548 LERP(in[
ixy(x + 1, y + 0)], in[
ixy(x + 1, y + 1)]);
553 LERP(in[
ixy(x + 0, y + 1)], in[
ixy(x + 1, y + 1)]);
560 LERP(in[
ixy(x + 0, y + 0)], in[
ixy(x + 0, y + 1)]);
607 }
catch (
const std::bad_alloc&) {
624 inline double LERP(T A, T B)
const {
626 return AB == 0 ? 0 :
static_cast<double>(A -
m_threshold) / AB;
655 for (
int i = first; i < last; i++) {
670 for (
int i = 0; i < l; i++) mean +=
getContourX(contour, i);
671 return (l == 0 ? 0 : mean / l);
677 for (
int i = 0; i < l; i++) mean +=
getContourY(contour, i);
678 return (l == 0 ? 0 : mean / l);
686 for (
int i = first; i < last; i++) perim +=
measureLength(contour, i);
706 for (
int i = first; i < last; i++) ret +=
measureNormalY(contour, i);
712 for (
int i = first; i < last; i++) ret +=
measureNormalX(contour, i);
718 for (
int i = first; i <= last; i++) sum +=
measureAngle(contour, i);
722 static int wrap(
int i,
int lo,
int hi) {
735 printf(
"went below lo\n");
736 }
else if (w >= hi) {
738 printf(
"went above hi\n");
744 inline int ixy(
int x,
int y)
const {
return x + y *
m_w; }
749 return std::sqrt(dx * dx + dy * dy);
758 int v1 =
wrap(lo + i + 0, lo, hi);
759 int v2 =
wrap(lo + i + 1, lo, hi);
764 return std::sqrt(aftx * aftx + afty * afty);
775 double befl = std::sqrt(befx * befx + befy * befy);
778 double aftl = std::sqrt(aftx * aftx + afty * afty);
782 double dot = befx * aftx + befy * afty;
787 double rads = std::acos(
dot);
788 assert(rads == rads);
790 if (aftx * befy - afty * befx < 0) rads = -rads;
815 for (
int i = 0; i < l; i++) {
828 for (
int i = 0; i < l; i++) {
854 if (numContours == 0) {
863 m_minx.resize(numContours);
864 m_miny.resize(numContours);
865 m_maxx.resize(numContours);
866 m_maxy.resize(numContours);
867 }
catch (
const std::bad_alloc&) {
872 for (
int k = 0; k < numContours; k++) {
902 for (
int i = 0, j = -1; i < l; j = i++) {
905 if ((yj > y) != (yi > y)) {
909 if (x < xi) inside = !inside;
910 }
else if (x < xi + (y - yi) * (xi - xj) / (yi - yj)) {
931 int k,
double minx,
double miny,
double maxx,
double maxy)
const {
937 const std::vector<double>& polyy,
941 size_t l = polyx.size();
942 if (l < 1)
return false;
943 for (
size_t i = 0, j = l - 1; i < l; j = i++) {
944 double yi = polyy[i];
945 double yj = polyy[j];
946 if ((yj > y) != (yi > y)) {
947 double xi = polyx[i];
948 double xj = polyx[j];
950 if (x < xi) inside = !inside;
951 }
else if (x < xi + (y - yi) * (xi - xj) / (yi - yj)) {
970 double lt = minx1 > minx2 ? minx1 : minx2;
971 double rt = maxx1 < maxx2 ? maxx1 : maxx2;
972 double tp = miny1 > miny2 ? miny1 : miny2;
973 double bt = maxy1 < maxy2 ? maxy1 : maxy2;
975 return (lt < rt && tp < bt);
988 return (minx1 <= minx2 && maxx1 >= maxx2 && miny1 <= miny2 &&
ConfigurationCodes
2x2 cell configuration codes
std::vector< double > m_maxx
std::vector< double > m_minx
double getBBCenterY(int k) const
bool bbContainsBB(int k1, int k2) const
int getContourLength(int contour) const
Returns the length of a given contour.
int getMaxContour() const
void setThreshold(T t)
Sets isoline value to trace.
static int wrap(int i, int lo, int hi)
void setContourX(int contour, int v, double x)
int getValidIndex(int contour, int v) const
double measureAngleChange(int contour, int first, int last) const
void getContourPoint(int contour, size_t index, double &x, double &y) const
Returns the given point (x,y) of a given contour.
int findIsolines(const T *in)
Searches image for contours from topleft to bottomright corners.
double getContourY(int contour, int v) const
bool contains(int k, double x, double y) const
double getBBMinY(int contour) const
double measureDistance(int contour, int first, int second) const
void createOnePixelBorder(T *in, T borderval) const
Creates a single pixel, 0-valued border around the grid.
int find(const T *in)
Find isolines.
bool containsBoundingBox(int k, double minx, double miny, double maxx, double maxy) const
double getBBMaxX(int contour) const
double bbArea(int k) const
double measureMeanY(int contour) const
std::vector< int > m_contourIndexes
std::vector< double > m_contourY
bool isContourClosed(int contour) const
Returns whether a given contour is closed or not.
int ixy(int x, int y) const
void findRoundedCorners(int window, std::vector< double > &tips)
double measureNormalX(int contour, int first, int last) const
void findAreas(int window, std::vector< double > &tips)
double measureLength(int contour, int i) const
double getContourX(int contour, int v) const
double measureMeanX(int contour) const
double measureCurvature(int contour, int i) const
bool computeBoundingBoxes()
std::vector< double > m_contourX
std::vector< double > m_miny
double measureNormalX(int contour, int i) const
double measurePerimeter(int contour) const
Measures the perimeter of a given contour.
double measureAngle(int contour, int i) const
double measureNormalY(int contour, int first, int last) const
std::vector< int > m_contourLength
int getNumContours() const
Returns the number of found contours.
std::vector< bool > m_contourClosed
void endContour(bool closed, bool alternatePath)
double getBBMinX(int contour) const
Isolines(int w, int h)
Default constructor.
void setContourY(int contour, int v, double y)
double getBBCenterX(int k) const
bool containsContour(int k1, int k2)
double measurePerimeter(int contour, int first, int last) const
double measureArea(int contour, int first, int last) const
std::vector< double > m_maxy
bool contains(const std::vector< double > &polyx, const std::vector< double > &polyy, double x, double y) const
double measureNormalY(int contour, int i) const
std::vector< int > m_contourOrigin
double measureArea(int contour) const
Measures the area delineated by a given contour.
bool bbIntersect(int k1, int k2) const
double LERP(T A, T B) const
LERP between two values.
void preCodeImage(const T *in)
Computes a code for each group of 4x4 cells.
double getBBMaxY(int contour) const
__host__ __device__ float length(float2 v)
__host__ __device__ float dot(float2 a, float2 b)