Skip to content

Commit a3ef95c

Browse files
committed
fix(vendor/kik/scanner): handle ellipsis bounds by clamping
Signed-off-by: Brandon McAnsh <[email protected]>
1 parent b3a099a commit a3ef95c

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

vendor/kik/scanner/src/main/cpp/scan/scanner.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,14 @@ bool detectKikCode(Mat &greyscale, Mat *out_progress, uint32_t device_quality, u
555555
}
556556

557557
Moments moment = mu[i];
558-
558+
559+
// --- START OF EDIT ---
560+
// CHANGE: Skip invalid moments; decision: m00<=0 -> NaN in area/perimeter/inertia.
561+
if (moment.m00 <= 0) {
562+
continue;
563+
}
564+
// --- END OF EDIT ---
565+
559566
// the contour must be...
560567
// large enough
561568
const double minimum_ellipse_area = 220 * scaling_rate;
@@ -642,6 +649,12 @@ bool detectKikCode(Mat &greyscale, Mat *out_progress, uint32_t device_quality, u
642649
// ++timing->ellipses_fit;
643650
RotatedRect rect = fitEllipse(contour);
644651

652+
// CHANGE: Clamp post-fit; decision: fitEllipse can return <=0 on edge cases (e.g., collinear points).
653+
// Problem: Negative/zero size -> assertion in ellipse() drawing.cpp:1883.
654+
// Fix: Min 1px; preserves shape but ensures validity (per OpenCV drawing module reqs).
655+
rect.size.width = std::max(1.0f, rect.size.width);
656+
rect.size.height = std::max(1.0f, rect.size.height);
657+
645658
#if DEBUGGING
646659
if (output_snapshots) {
647660
drawContours(contour_selection, contours, i, Scalar(255, 0, 0), 1, 8, hierarchy, 0, Point2i());
@@ -653,6 +666,12 @@ bool detectKikCode(Mat &greyscale, Mat *out_progress, uint32_t device_quality, u
653666
rect.size.width -= 2;
654667
rect.size.height -= 2;
655668

669+
// --- START OF EDIT ---
670+
// CHANGE: Re-clamp after subtract; decision: -=2 on small rect (e.g., 2.5->0.5) -> negative.
671+
rect.size.width = std::max(1.0f, rect.size.width);
672+
rect.size.height = std::max(1.0f, rect.size.height);
673+
// --- END OF EDIT ---
674+
656675
// track the contour that started this ellipse
657676
ellipse_contours.push_back(contour);
658677

@@ -681,20 +700,24 @@ bool detectKikCode(Mat &greyscale, Mat *out_progress, uint32_t device_quality, u
681700
// fitting tolerance (+/-2 pixels)
682701
vector<vector<Point2i>> pruned_contours;
683702

684-
for (int i = 0; i < ellipse_contours.size(); ++i) {
685-
vector<Point2i> &contour = ellipse_contours[i];
703+
// --- START OF EDIT ---
704+
// CHANGE: Added post-prune size check; decision: Skip empty/<5 pt contours to avoid degenerate fitEllipse in _2.
705+
// Problem: Over-pruning from noisy masks -> tiny pruned_contour -> repeat upstream crash in ellipse_fitting_2.
706+
// Fix: Only push if viable; reduces false candidates, improves perf (fewer refits).
707+
for (auto & contour : ellipse_contours) {
686708
vector<Point2i> pruned_contour;
687709

688-
for (int j = 0; j < contour.size(); ++j) {
689-
Point2i &point = contour[j];
690-
691-
if (matches_near_ellipses.at<char>(point.y, point.x) != 0) {
710+
for (auto & point : contour) {
711+
int py = point.y, px = point.x;
712+
if (py >= 0 && py < matches_near_ellipses.rows && px >= 0 && px < matches_near_ellipses.cols &&
713+
matches_near_ellipses.at<char>(py, px) != 0) {
692714
pruned_contour.push_back(point);
693715
}
694716
}
695717

696718
pruned_contours.push_back(pruned_contour);
697719
}
720+
// --- END OF EDIT ---
698721

699722
vector<vector<Point2i> > contours2 = pruned_contours;
700723
vector<Vec4i> hierarchy2;

0 commit comments

Comments
 (0)