mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
ported changes from c++ f80a9b923a14827cc78bb96703676c14ac61c1ed
This commit is contained in:
@@ -19,7 +19,7 @@
|
|||||||
// import com.google.zxing.NotFoundException;
|
// import com.google.zxing.NotFoundException;
|
||||||
|
|
||||||
use crate::common::Result;
|
use crate::common::Result;
|
||||||
use crate::{point_f, Exceptions, Point};
|
use crate::{point, point_f, Exceptions, Point};
|
||||||
|
|
||||||
use super::{BitMatrix, GridSampler, SamplerControl};
|
use super::{BitMatrix, GridSampler, SamplerControl};
|
||||||
|
|
||||||
@@ -42,22 +42,17 @@ impl GridSampler for DefaultGridSampler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for SamplerControl { p0, p1, transform } in controls {
|
for SamplerControl { p0, p1, transform } in controls {
|
||||||
// To deal with remaining examples (see #251 and #267) of "numercial instabilities" that have not been
|
// Precheck the corners of every roi to bail out early if the grid is "obviously" not completely inside the image
|
||||||
// prevented with the Quadrilateral.h:IsConvex() check, we check for all boundary points of the grid to
|
let isInside = |x: f32, y: f32| {
|
||||||
// be inside.
|
image.is_in(transform.transform_point(Point::centered(point(x, y))))
|
||||||
let isInside =
|
};
|
||||||
|p: Point| -> bool { image.is_in(transform.transform_point(p.centered())) };
|
if (!transform.isValid()
|
||||||
for y in (p0.y as i32)..(p1.y as i32) {
|
|| !isInside(p0.x, p0.y)
|
||||||
// for (int y = y0; y < y1; ++y)
|
|| !isInside(p1.x - 1.0, p0.y)
|
||||||
if !isInside(point_f(p0.x, y as f32)) || !isInside(point_f(p1.x - 1.0, y as f32)) {
|
|| !isInside(p1.x - 1.0, p1.y - 1.0)
|
||||||
return Err(Exceptions::NOT_FOUND);
|
|| !isInside(p0.x, p1.y - 1.0))
|
||||||
}
|
{
|
||||||
}
|
return Err(Exceptions::NOT_FOUND);
|
||||||
for x in (p0.x as i32)..(p1.x as i32) {
|
|
||||||
// for (int x = x0; x < x1; ++x)
|
|
||||||
if !isInside(point_f(x as f32, p0.y)) || !isInside(point_f(x as f32, p1.y - 1.0)) {
|
|
||||||
return Err(Exceptions::NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +68,15 @@ impl GridSampler for DefaultGridSampler {
|
|||||||
if image.get_point(p) {
|
if image.get_point(p) {
|
||||||
bits.set(x as u32, y as u32);
|
bits.set(x as u32, y as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Due to a "numerical instability" in the PerspectiveTransform generation/application it has been observed
|
||||||
|
// that even though all boundary grid points get projected inside the image, it can still happen that an
|
||||||
|
// inner grid points is not. See #563. A true perspective transformation cannot have this property.
|
||||||
|
// The following check takes 100% care of the issue and turned out to be less of a performance impact than feared.
|
||||||
|
// TODO: Check some mathematical/numercial property of mod2Pix to determine if it is a perspective transforation.
|
||||||
|
if (!image.is_in(p)) {
|
||||||
|
return Err(Exceptions::NOT_FOUND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,10 @@ impl PerspectiveTransform {
|
|||||||
self.a11 * self.a22 - self.a12 * self.a21,
|
self.a11 * self.a22 - self.a12 * self.a21,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn isValid(&self) -> bool {
|
||||||
|
!self.a33.is_nan()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul for PerspectiveTransform {
|
impl Mul for PerspectiveTransform {
|
||||||
|
|||||||
Reference in New Issue
Block a user