diff --git a/toonz/sources/toonzlib/autopos.cpp b/toonz/sources/toonzlib/autopos.cpp index 33dd585..911b32f 100644 --- a/toonz/sources/toonzlib/autopos.cpp +++ b/toonz/sources/toonzlib/autopos.cpp @@ -563,10 +563,14 @@ visit_bw(int i, int j, int x, int y, int bit, UCHAR *byte), #endif visit_gr8(int i, int j, int x, int y, UCHAR *pix), visit_rgb(int i, int j, int x, int y, TPixel32 *pix), - stampa_dot(DOT *dot); + stampa_dot(DOT const*dot); +//! \brief Find the best matching pegs +//! +//! The found pegs are in array dots. The function checks, which of those best fits the reference in +//! reference. The three best matching dots are returned in parameters i, j, k. static int -compare_dots(DOT dots[], int *ndots, DOT reference[], int ref_dot); +compare_dots(DOT const dots[], int ndots, DOT reference[], int ref_dot, int& i, int& j, int& k); #define REVERSE(byte, bit) \ { \ @@ -1025,8 +1029,8 @@ static int find_dots_rgb(const TRaster32P &img, int strip_width, PEGS_SIDE pegs_ if (Npix < max_area * 3 / 2 && dot_lx > 3 && dot_lx < (xsize >> 1) && dot_ly > 3 && dot_ly < (ysize >> 1) && - Xmin > x0 && Xmax < xlast && - Ymin > y0 && Ymax < ylast) { + Xmin > x0 && Xmax <= xlast && + Ymin > y0 && Ymax <= ylast) { dot_x = (float)(BIG_TO_DOUBLE(Xsum) / BIG_TO_DOUBLE(Weightsum)); dot_y = (float)(BIG_TO_DOUBLE(Ysum) / BIG_TO_DOUBLE(Weightsum)); if (vertical) { @@ -1428,6 +1432,7 @@ static void visit_rgb(int i, int j, int x, int y, TPixel32 *pix) #endif +#define PERCENT (40.0 / 100.0) /*---------------------------------------------------------------------------*/ /* * Attenzione: tutti i controlli e i calcoli vengono fatti in pixel. @@ -1445,8 +1450,8 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, float dx, dy; DOT _dotarray[MAX_DOT]; DOT *dotarray = _dotarray; - int ndot, central; - int max_area; + int ndot; + int max_area, min_area; *p_ang = 0.0; @@ -1458,9 +1463,21 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, } max_area = 0; + if (ref_dot > 0) + { + min_area = ref[0].area; + } for (i = 0; i < ref_dot; i++) + { if (ref[i].area > max_area) + { max_area = ref[i].area; + } + if (ref[i].area < min_area) + { + min_area = ref[i].area; + } + } ndot = find_dots(img, strip_width, pegs_side, dotarray, MAX_DOT, max_area); if (Debug_flag) @@ -1469,7 +1486,7 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, i = 0; while (i < ndot) //elimino i dots troppo piccoli { - if (dotarray[i].area < 500) { + if (dotarray[i].area < min_area * PERCENT) { for (int j = i; j < ndot - 1; j++) dotarray[j] = dotarray[j + 1]; ndot--; @@ -1482,7 +1499,8 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, return FALSE; } - found = compare_dots(dotarray, &ndot, ref, ref_dot); + int indexArray[3] = { 0, 1, 2 }; + found = compare_dots(dotarray, ndot, ref, ref_dot, indexArray[0], indexArray[1], indexArray[2]); if (Debug_flag) for (i = 0; i < ndot; i++) { @@ -1493,12 +1511,10 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, if (!found) return FALSE; - central = ndot / 2; - angle = 0; - for (i = 0; i < ndot - 1; i++) { - dx = dotarray[i + 1].x - dotarray[i].x; - dy = dotarray[i + 1].y - dotarray[i].y; + for (i = 0; i < 2; i++) { + dx = dotarray[indexArray[i + 1]].x - dotarray[indexArray[i]].x; + dy = dotarray[indexArray[i + 1]].y - dotarray[indexArray[i]].y; switch (pegs_side) { case PEGS_LEFT: case PEGS_RIGHT: @@ -1510,9 +1526,16 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, } } - *p_ang = angle / (ndot - 1); - *cx = dotarray[central].x; - *cy = dotarray[central].y; + *p_ang = angle / 2; + + // Now calculate the center, we have to get the offset of the center for the dot at point indexArray[1] + // from the reference and then use the angle to calculate the offsets for the center. + // + // It is assumed, that the holes are all on one line. + float pegWidth = sqrt((ref[ref_dot - 1].x - ref[0].x) * (ref[ref_dot - 1].x - ref[0].x) + (ref[ref_dot - 1].y - ref[0].y) * (ref[ref_dot - 1].y - ref[0].y)); + float refPegOffset = sqrt((ref[indexArray[1]].x - ref[0].x) * (ref[indexArray[1]].x - ref[0].x) + (ref[indexArray[1]].y - ref[0].y) * (ref[indexArray[1]].y - ref[0].y)); + *cx = dotarray[indexArray[1]].x + cos(*p_ang) * (pegWidth / 2.0f - refPegOffset); + *cy = dotarray[indexArray[1]].y + sin(*p_ang) * (pegWidth / 2.0f - refPegOffset); if (Debug_flag) { printf("\nang: %g\ncx : %g\ncy : %g\n\n", *p_ang, *cx, *cy); @@ -1522,53 +1545,49 @@ int get_image_rotation_and_center(const TRasterP &img, int strip_width, } /*---------------------------------------------------------------------------*/ -#define PERCENT (40.0 / 100.0) #define MIN_V 100.0 -static int compare_dots(DOT dots[], int *ndots, - DOT reference[], int ref_dot) +static int compare_dots(DOT const dots[], int ndots, DOT reference[], int ref_dot, int& i_ok, int& j_ok, int& k_ok) { int found; - int toll, i_ok = 0, j_ok = 0, k_ok = 0; + int toll; float tolld; int i, j, k; - short *dot_ok = 0; + bool *dot_ok = 0; float *ref_dis = 0, dx, dy; float vmin, v, dist_i_j, dist_i_k, dist_j_k, del1, del2; float ref_dis_0_1, ref_dis_1_2; + i_ok = 0; + j_ok = 0; + k_ok = 0; + /* questa funz e' indipendente da posizione e orientamento dei dots */ - if (*ndots < 1 || ref_dot < 1) { + if (ndots < 1 || ref_dot < 1) { goto error; } /* controllo quanti dots sono realmente buoni per il confronto */ - dot_ok = (short *)calloc(*ndots, sizeof(short)); + dot_ok = (bool *)calloc(ndots, sizeof(bool)); found = 0; - for (i = 0; i < *ndots; i++) + for (i = 0; i < ndots; i++) { + dot_ok[i] = false; for (j = 0; j < ref_dot; j++) { toll = (int)((float)reference[j].area * PERCENT); if (abs(dots[i].area - reference[j].area) < toll) { - dot_ok[found] = i; + dot_ok[i] = true; found++; break; } } + } if (!found) { goto error; } - if (found < *ndots) { - for (i = 0; i < found; i++) { - if (dot_ok[i] != i) - *(dots + i) = *(dots + dot_ok[i]); - } - *ndots = found; - } - ref_dis = (float *)calloc(ref_dot, sizeof(float)); /* calcolo le distanze di riferimento e la tolleranza stessa */ @@ -1592,9 +1611,17 @@ static int compare_dots(DOT dots[], int *ndots, i_ok = -1; v = vmin = 10000000.0; - for (i = 0; i < *ndots - 2; i++) - for (j = i + 1; j < *ndots - 1; j++) - for (k = j + 1; k < *ndots; k++) { + for (i = 0; i < ndots - 2; i++) { + if (!dot_ok[i]) + continue; + + for (j = i + 1; j < ndots - 1; j++) { + if (!dot_ok[j]) + continue; + for (k = j + 1; k < ndots; k++) { + if (!dot_ok[k]) + continue; + // Build square discrepancies from the reference relative hole distances dx = dots[i].x - dots[j].x; dy = dots[i].y - dots[j].y; @@ -1618,6 +1645,8 @@ static int compare_dots(DOT dots[], int *ndots, vmin = v; } } + } + } if (Debug_flag) { printf("Ho trovato v = %f su %f per %d %d %d \n", @@ -1647,12 +1676,11 @@ static int compare_dots(DOT dots[], int *ndots, dy = reference[1].y - reference[2].y; ref_dis_1_2 = sqrtf((dx * dx) + (dy * dy)); - if (fabsf(dist_i_j - ref_dis_0_1) < tolld && - fabsf(dist_j_k - ref_dis_1_2) < tolld) { - *ndots = 3; - *(dots) = *(dots + i_ok); - *(dots + 1) = *(dots + j_ok); - *(dots + 2) = *(dots + k_ok); + if (fabsf(dist_i_j - ref_dis_0_1) >= tolld || + fabsf(dist_j_k - ref_dis_1_2) >= tolld) { + i_ok = 0; + j_ok = 1; + k_ok = 2; } } @@ -1672,7 +1700,7 @@ error: } /*---------------------------------------------------------------------------*/ -static void stampa_dot(DOT *dot) +static void stampa_dot(DOT const*dot) { printf("Dimensioni: %d,\t%d\n", dot->lx, dot->ly); printf("Start : %d,\t%d\n", dot->x1, dot->y1); diff --git a/toonz/sources/toonzlib/cleanupparameters.cpp b/toonz/sources/toonzlib/cleanupparameters.cpp index 55166a3..1b010d7 100644 --- a/toonz/sources/toonzlib/cleanupparameters.cpp +++ b/toonz/sources/toonzlib/cleanupparameters.cpp @@ -135,8 +135,8 @@ void FdgManager::loadFieldGuideInfo() sscanf(arg, "%d", &cnt); if (cnt >= (int)fdg_info.dots.size()) { // tmsg_error("load field guide info error: bad hole number"); - break; // return FALSE; + fdg_info.dots.push_back(CleanupTypes::DOT()); } } else if (STR_EQ(label, "X0")) sscanf(arg, "%d", &fdg_info.dots[cnt].x1);