static DetectorResult ProcessFinderPatternInfo(const BitMatrix& image, const FinderPatternInfo& info) { float moduleSize = CalculateModuleSize(image, info.topLeft, info.topRight, info.bottomLeft); if (moduleSize < 1.0f) { return {}; } int dimension = ComputeDimension(info.topLeft, info.topRight, info.bottomLeft, moduleSize); if (dimension < 0) return {}; const Version* provisionalVersion = Version::ProvisionalVersionForDimension(dimension); if (provisionalVersion == nullptr) return {}; int modulesBetweenFPCenters = provisionalVersion->dimensionForVersion() - 7; AlignmentPattern alignmentPattern; // Anything above version 1 has an alignment pattern if (!provisionalVersion->alignmentPatternCenters().empty()) { // Guess where a "bottom right" finder pattern would have been float bottomRightX = info.topRight.x() - info.topLeft.x() + info.bottomLeft.x(); float bottomRightY = info.topRight.y() - info.topLeft.y() + info.bottomLeft.y(); // Estimate that alignment pattern is closer by 3 modules // from "bottom right" to known top left location float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters; int estAlignmentX = static_cast<int>(info.topLeft.x() + correctionToTopLeft * (bottomRightX - info.topLeft.x())); int estAlignmentY = static_cast<int>(info.topLeft.y() + correctionToTopLeft * (bottomRightY - info.topLeft.y())); // Kind of arbitrary -- expand search radius before giving up for (int i = 4; i <= 16; i <<= 1) { alignmentPattern = FindAlignmentInRegion(image, moduleSize, estAlignmentX, estAlignmentY, static_cast<float>(i)); if (alignmentPattern.isValid()) break; } // If we didn't find alignment pattern... well try anyway without it } PerspectiveTransform transform = CreateTransform(info.topLeft, info.topRight, info.bottomLeft, alignmentPattern, dimension); auto bits = GridSampler::Instance()->sampleGrid(image, dimension, dimension, transform); if (bits.empty()) return {}; if (alignmentPattern.isValid()) return {std::move(bits), {info.bottomLeft, info.topLeft, info.topRight, alignmentPattern}}; else return {std::move(bits), {info.bottomLeft, info.topLeft, info.topRight}}; }
//----------------------------------------------------------------------------- void Region::ComputeWith( Region &anchor ) { if( !anchor.m_computed_valid ) { // anchor isn't computed. return; } ComputeDimension( anchor, 0 ); // catch negative width if( m_computed_size[0] < 0 ) { return; } ComputeDimension( anchor, 1 ); if( m_computed_size[1] < 0 ) { return; } m_computed_valid = true; }