Commit 67493e2ed8ae13c24f1fcbd4819b0ed1a28efb96

There we go.
c/azy.c
(20 / 16)
  
3232#define show(image)
3333#endif
3434
35#define RETARD_CAST(x) ((long unsigned int )(int )(x))
36
3537// The following procedures may mangle their outputs in case of a failure.
3638
3739bool azy_icp(CvMat* result_, // Icp means iterative closest point, eventually.
5050 for (size_t index = 0;
5151 index < total;
5252 ++index) {
53 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, fixed, index);
53 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, fixed, RETARD_CAST(index));
5454 int const x = pt->x;
5555 int const y = pt->y;
5656 cvSet2D(fmat, (int )index, 0, cvScalarAll(x));
5959 for (size_t index = 0;
6060 index < total;
6161 ++index) {
62 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, moving, index);
62 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, moving, RETARD_CAST(index));
6363 int const x = pt->x;
6464 int const y = pt->y;
6565 cvSet2D(mmat, (int )index, 0, cvScalarAll(x));
115115 struct position value;
116116 status &= azy_bezier(&value, points, point_count, (double )index * normalization);
117117 CvPoint point = {
118 .x = value.x,
119 .y = value.y
118 .x = (int )value.x,
119 .y = (int )value.y
120120 };
121 cvSeqInsert(result_, offset, &point);
121 cvSeqInsert(result_, (int )offset, &point);
122122 }
123123
124124 return status;
581581 for (size_t index4 = 0;
582582 index4 < total;
583583 ++index4) {
584 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], index4);
584 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], RETARD_CAST(index4));
585585 int const x = pt->x;
586586 int const y = pt->y;
587587 // Off-by-one errors have already accumulated to three.
618618 index4 < total;
619619 ++index4) {
620620 size_t const index5 = (index4 + one) % total;
621 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], index5);
621 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], RETARD_CAST(index5));
622622 int const x = pt->x;
623623 int const y = pt->y;
624624 bool const next = x < 3
662662 if (index2 == 0)
663663 rln = partial_blob_sizes[index2][index3];
664664 else
665 rln += (rln + partial_blob_sizes[index2][index3]) / 2;
665 rln = fmax(rln, (double )partial_blob_sizes[index2][index3]);
666666 }
667667 say("Dandy consensus of %f.", rln);
668 // Must make guesses here if all blobs clip.
668669
669670 say("Considering the lazy way.");
670671 // Pick a complete blob if it agrees with the blob size.
715715 size_t const end_focus_index = (end_index - focus + total) % total;
716716 say("Clip and focus indices %zu, %zu, %zu, %zu.",
717717 start_index, start_focus_index, end_focus_index, end_index);
718 CvPoint* p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], start_index);
718 CvPoint* p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], RETARD_CAST(start_index));
719719 CvPoint start = *p;
720 p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], end_index);
720 p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], RETARD_CAST(end_index));
721721 CvPoint end = *p;
722 p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], start_focus_index);
722 p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], RETARD_CAST(start_focus_index));
723723 CvPoint start_focus = *p;
724 p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], end_focus_index);
724 p = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][index3], RETARD_CAST(end_focus_index));
725725 CvPoint end_focus = *p;
726726 say("Focusing through (%d, %d), (%d, %d), (%d, %d), (%d, %d).",
727727 start.x, start.y,
770770 double ass;
771771 some_distance_thing(&ass, &start, &end);
772772 size_t const dots = (size_t )ass;
773 cvSeqRemoveSlice(blob_contours[index2][index3], cvSlice(end_index, start_index));
773 CvSlice slice = cvSlice((int )end_index, (int )start_index);
774 cvSeqRemoveSlice(blob_contours[index2][index3], slice);
774775 struct position starter_tangent = {
775776 .x = radius * start_normal.x + starter.x,
776777 .y = radius * start_normal.y + starter.y
819819 end_focus.x += offshit.x; end_focus.y += offshit.y;
820820 cvCircle(safe.pixels, end_focus, 3, CV_RGB(255, 128, 64), 1, 4/*_CONNECTED*/, 0);
821821 start_tangent.x += offshit.x; start_tangent.y += offshit.y;
822 cvCircle(safe.pixels, start_tangent, 5, CV_RGB(255, 128, 64), 1, 4/*_CONNECTED*/, 0);
822 cvCircle(safe.pixels, start_tangent, 3, CV_RGB(255, 128, 64), 1, 4/*_CONNECTED*/, 0);
823823 end_tangent.x += offshit.x; end_tangent.y += offshit.y;
824 cvCircle(safe.pixels, end_tangent, 5, CV_RGB(255, 128, 64), 1, 4/*_CONNECTED*/, 0);
824 cvCircle(safe.pixels, end_tangent, 3, CV_RGB(255, 128, 64), 1, 4/*_CONNECTED*/, 0);
825825 }
826826 show(&safe);
827827 azy_destroy_colorful_image_(&safe);
864864 for (size_t index4 = 0;
865865 index4 < total;
866866 ++index4) {
867 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][0], index4);
867 CvPoint* pt = (CvPoint* )CV_GET_SEQ_ELEM(CvPoint, blob_contours[index2][0], RETARD_CAST(index4));
868868 pt->x += (int )xoff;
869869 pt->y += (int )yoff;
870870 }
c/makefile
(8 / 12)
  
33 \
44 -Wno-unused-parameter \
55 -Wno-aggregate-return -Wno-padded \
6 -Wno-suggest-attribute=const -Wno-missing-declarations # transient
6 -Wno-suggest-attribute=const -Wno-missing-declarations -Wno-float-equal # transient
77debug=$(warnings) -DVERBOSE -DVISUAL -O2 -g
88deploy=-O3 -s
99CFLAGS=$(debug) \
4242# ../../samples/019-5/l_1397038164_65.png \
4343# ../../samples/019-5/l_1397038164_82.png \
4444# #
45 # expected 12 -> 28
46 # 1.02 0.13 -7.5
47 # -0.26 1.09 297.5
48 # 0 0 1.0
49# - ./azier \
50# ../../samples/061-1/l_1396438664_12.png \
51# ../../samples/061-1/l_1396438664_28.png \
45 - ./azier \
46 ../../samples/061-1/l_1396438664_12.png \
47 ../../samples/061-1/l_1396438664_28.png \
5248# # \
5349# ../../samples/061-1/l_1396438663_97.png \
5450# ../../samples/061-1/l_1396438664_12.png \
5551# ../../samples/061-1/l_1396438664_28.png \
5652# ../../samples/061-1/l_1396438664_45.png \
5753# #
58 - ./azier \
59 ../../samples/054-1/l_1405938179_02.png \
60 ../../samples/054-1/l_1405938179_17.png \
61 ../../samples/054-1/l_1405938179_34.png \
54# - ./azier \
55# ../../samples/054-1/l_1405938179_02.png \
56# ../../samples/054-1/l_1405938179_17.png \
57# ../../samples/054-1/l_1405938179_34.png \
6258# # \
6359# ../../samples/054-1/l_1405938178_89.png \
6460# ../../samples/054-1/l_1405938179_02.png \
log/log.tex
(25 / 2)
  
250250 & = \sqrt{5 - 2 \sqrt 5}.
251251\end{align*}
252252
253If that is a bad idea, here is another one.
254In case all areas are incomplete, approximate the sample with a sphere and
255calculate the likely complete area $A_c$ for the previous algorithm.
256Here is how: let $c$ be clip or chord length,
257$d$ be chord-aligned maximal diameter and so
258\begin{align*}
259 A_c'
260 & = A_i + A_r \\ % obvious
261 A_c'
262 & = \frac{2\pi d^2} 8 % circle
263 \Leftrightarrow \\
264 d
265 & =
266 \sqrt{\frac{8 A_c'}{2\pi}} \\ % chord
267 \theta
268 & = 2 \arcsin\frac c d \\ % chord
269 A_r
270 & = \frac{d^2} 8 (\theta - \sin\theta) \\ % chord
271 A_c
272 & = A_i + A_r. % obvious
273\end{align*}
274
253275Back to the algorithm.
254276Only matching the images and combining them is left to be done.
255277For each pair, again, do the following.
304304
305305There is still a problem with clipping.
306306Long appendages and tangential bodies count as clipped regions.
307There must be a tolerance length below which clipping is ignored.
307There must be a tolerance length below which clipping is ignored or
308only one clipping could be allowed per sample.
308309
309310Morphological skeletons are a bad idea.
310311They did not work.
314314maxima (by distances from the centroids).
315315
316316Almost forgot the sharpness detection.
317It is trivial. \ref{pr}
317It is trivial. \cite{pr}
318318
319319\begin{figure}[b]
320320 \centering