#include "GridSampler.h"
#ifdef PRINT_DEBUG
#include "LogMatrix.h"
#include "BitMatrixIO.h"
#endif
namespace ZXing {
#ifdef PRINT_DEBUG
LogMatrix log;
#endif
DetectorResult SampleGrid(const BitMatrix& image, int width, int height, const PerspectiveTransform& mod2Pix)
{
return SampleGrid(image, width, height, {ROI{0, width, 0, height, mod2Pix}});
}
DetectorResult SampleGrid(const BitMatrix& image, int width, int height, const ROIs& rois)
{
#ifdef PRINT_DEBUG
LogMatrix log;
static int i = 0;
LogMatrixWriter lmw(log, image, 5, "grid" + std::to_string(i++) + ".pnm");
#endif
if (width <= 0 || height <= 0)
return {};
for (auto&& [x0, x1, y0, y1, mod2Pix] : rois) {
auto isInside = [&mod2Pix = mod2Pix, &image](int x, int y) { return image.isIn(mod2Pix(centered(PointI(x, y)))); };
if (!mod2Pix.isValid() || !isInside(x0, y0) || !isInside(x1 - 1, y0) || !isInside(x1 - 1, y1 - 1) || !isInside(x0, y1 - 1))
return {};
}
BitMatrix res(width, height);
for (auto&& [x0, x1, y0, y1, mod2Pix] : rois) {
for (int y = y0; y < y1; ++y)
for (int x = x0; x < x1; ++x) {
auto p = mod2Pix(centered(PointI{x, y}));
if (!image.isIn(p))
return {};
#ifdef PRINT_DEBUG
log(p, 3);
#endif
#if 0#else
if (image.get(p))
#endif
res.set(x, y);
}
}
#ifdef PRINT_DEBUG
printf("width: %d, height: %d\n", width, height);
#endif
auto projectCorner = [&](PointI p) {
for (auto&& [x0, x1, y0, y1, mod2Pix] : rois)
if (x0 <= p.x && p.x <= x1 && y0 <= p.y && p.y <= y1)
return PointI(mod2Pix(PointF(p)) + PointF(0.5, 0.5));
return PointI();
};
return {std::move(res),
{projectCorner({0, 0}), projectCorner({width, 0}), projectCorner({width, height}), projectCorner({0, height})}};
}
DetectorResult SampleGrid(const BitMatrix& image, int width, int height, const PerspectiveTransform& mod2Pix,
Matrix<std::optional<PointF>>&& apP, const std::vector<int>& apMX, const std::vector<int>& apMY)
{
const int W = Size(apMX) - 1, H = Size(apMY) - 1;
for (int y = 0; y <= H; ++y)
for (int x = 0; x <= W; ++x) {
if (apP(x, y)) {
#ifdef PRINT_DEBUG
log(*apP(x, y), 2);
#endif
} else {
#ifdef PRINT_DEBUG
printf("locate failed at %dx%d\n", x, y);
#endif
apP.set(x, y, mod2Pix(centered(PointI(apMX[x], apMY[y]))));
}
}
ROIs rois;
for (int y = 0; y < H; ++y)
for (int x = 0; x < W; ++x) {
int x0 = apMX[x], x1 = apMX[x + 1], y0 = apMY[y], y1 = apMY[y + 1];
rois.push_back({x == 0 ? 0 : x0, (x == W - 1) ? width : x1, (y == 0) ? 0 : y0, (y == H - 1) ? height : y1,
PerspectiveTransform{Rectangle(x0, x1, y0, y1, 0.5),
{*apP(x, y), *apP(x + 1, y), *apP(x + 1, y + 1), *apP(x, y + 1)}}});
}
return SampleGrid(image, width, height, rois);
}
}