Fix GetRotateCropImage: corner selection broken by OpenCV 4.13 RotatedRect convention change#188
Fix GetRotateCropImage: corner selection broken by OpenCV 4.13 RotatedRect convention change#188Kserol wants to merge 2 commits into
Conversation
Re-compile its underlaying opencv with older glibc and using https://github.com/NixOS/patchelf to load the standalone glibc in runtime is a way. |
Citation needed, I can't find issue about this in https://github.com/search?q=repo%3Aopencv%2Fopencv%20point%20order&type=issues&s=created&o=desc since the release of 4.13 on 2025-12-31.
That note was added by me in opencv/opencv#23342 to clarify opencv/opencv#23335 as opencvsharp refused to re-order points: shimat/opencvsharp#1541 like this PR. opencvsharp's own implement of |
| Point2f tl = rp.Aggregate((a, b) => (a.X + a.Y) <= (b.X + b.Y) ? a : b); | ||
| Point2f br = rp.Aggregate((a, b) => (a.X + a.Y) >= (b.X + b.Y) ? a : b); | ||
| Point2f tr = rp.Aggregate((a, b) => (a.Y - a.X) <= (b.Y - b.X) ? a : b); | ||
| Point2f bl = rp.Aggregate((a, b) => (a.Y - a.X) >= (b.Y - b.X) ? a : b); |
There was a problem hiding this comment.
If we are targeting .NET 6.0+ we may use .MinBy() and .MaxBy(), but sadly we are on .NET Standard 2.0:
|
Thanks for the detailed analysis and for tracking this down. I agree with the direction: Before merging, I would prefer to adjust the geometric ordering slightly. I already solved the same issue in OpenVINO.NET by using an
That avoids relying on angle/point-order conventions, but is also safer than Would you be open to updating this PR to use that ordering approach? The rest of the fix, especially deriving crop width/height from edge distances and rotating vertical crops based on the resulting aspect ratio, looks aligned with what we need. |
|
Thanks, that makes sense — min/max(x±y) can indeed collapse two corners into the same point near ±45° and produce a degenerate transform. I've updated the PR to use the OrderPointsClockwise approach from OpenVINO.NET (sort by X, split the left/right pairs, then disambiguate the left pair by Y and pick bottom-right as the right-most point farthest from top-left). The rest is unchanged: crop width/height derived from edge distances, and 90° rotation of vertical crops based on the aspect ratio. I kept the existing border/interpolation behaviour to minimize the diff. Re-validated on my French degraded-document set: still ~99.8% char accuracy / 0.98 confidence with OpenCvSharp 4.13. Let me know if you'd like any further tweaks. |
Summary
PaddleOcrAll.GetRotateCropImageselects the four crop corners fromRotatedRect.AngleandRotatedRect.Points()using a hard-coded ordering that assumes the OpenCV 4.11RotatedRectconvention. OpenCV 4.13 changed that convention (angle range /
points()order), so the samecode now picks the wrong corners. The perspective transform then maps corners incorrectly,
producing mirrored/rotated text-line crops and garbled recognition.
This is not a build/binding issue — recompiling Sdcb.PaddleOCR against OpenCvSharp 4.13 does not
help, because
rect.Angle/rect.Points()are runtime native values and the C# selection logicstays wrong.
Impact / reproduction
Same code, same model (
LocalFullModels.LatinV5), same images (degraded French document scans),only OpenCvSharp/OpenCV version differs:
The 4.13 result was reproduced with the NuGet
OpenCvSharp4.official.runtime.*natives andwith the official source-built native in
ghcr.io/shimat/opencvsharp/ubuntu24-dotnet10-opencv4.13.0,so it is the OpenCV 4.13
RotatedRectbehavior, not a packaging artifact.This matters because the OpenCvSharp 4.11 native does not load on modern glibc (≥ 2.34) base images
(ld.so
dl-versionassertion), so users on .NET 8/10 Linux images are pushed to 4.13 — where OCRsilently degrades.
Root cause
Both the
rp[...]index ordering and theangle-based flip/transpose depend on the exactRotatedRectconvention, which changed in OpenCV 4.13.Proposed fix
Order the four corners geometrically (convention-independent) and derive crop size from the
corner distances, instead of relying on
angle/Points()ordering:This mirrors PaddleOCR's reference
get_rotate_crop_image(geometric corner order + size from edgelengths) and is robust for the near-horizontal text lines detectors emit. Validated at 99.9 % char
accuracy on both OpenCvSharp 4.11 and 4.13.
Notes / open questions
min/max(x±y)ordering is robust for skew up to ~45°; for steeply rotated lines acentroid-angle sort could be considered, but detector boxes are near-horizontal in practice.
OpenCvSharp4dependency floor and noting 4.13 support,so downstreams know they can move off 4.11.