FinderPatternFinder
in package
This class attempts to find finder patterns in a QR Code. Finder patterns are the square markers at three corners of a QR Code.
This class is thread-safe but not reentrant. Each thread must allocate its own object.
Tags
Table of Contents
Constants
- CENTER_QUORUM = 2
- MAX_MODULES = 177
- MIN_SKIP = 2
Properties
- $hasSkipped : bool
- $matrix : BitMatrix
- $possibleCenters : array<string|int, FinderPattern>
Methods
- __construct() : mixed
- Creates a finder that will search the image for three finder patterns.
- find() : array<string|int, FinderPattern>
- centerFromEnd() : float
- Given a count of black/white/black/white/black pixels just seen and an end position, figures the location of the center of this run.
- crossCheckDiagonal() : bool
- After a vertical and horizontal scan finds a potential finder pattern, this method "cross-cross-cross-checks" by scanning down diagonally through the center of the possible finder pattern to see if the same proportion is detected.
- crossCheckHorizontal() : float|null
- Like #crossCheckVertical(int, int, int, int), and in fact is basically identical, except it reads horizontally instead of vertically. This is used to cross-cross check a vertical cross-check and locate the real center of the alignment pattern.
- crossCheckVertical() : float|null
- After a horizontal scan finds a potential finder pattern, this method "cross-checks" by scanning down vertically through the center of the possible finder pattern to see if the same proportion is detected.
- crossProductZ() : float
- Returns the z component of the cross product between vectors BC and BA.
- doShiftCounts2() : array<string|int, int>
- findRowSkip() : int
- foundPatternCross() : bool
- foundPatternDiagonal() : bool
- foundPatternVariance() : bool
- getCrossCheckStateCount() : array<string|int, int>
- handlePossibleCenter() : bool
- This is called when a horizontal scan finds a possible alignment pattern. It will cross-check with a vertical scan, and if successful, will, ah, cross-cross-check with another horizontal scan. This is needed primarily to locate the real horizontal center of the pattern in cases of extreme skew.
- haveMultiplyConfirmedCenters() : bool
- orderBestPatterns() : array<string|int, FinderPattern>
- Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
- selectBestPatterns() : array<string|int, FinderPattern>
Constants
CENTER_QUORUM
private
mixed
CENTER_QUORUM
= 2
MAX_MODULES
private
mixed
MAX_MODULES
= 177
MIN_SKIP
private
mixed
MIN_SKIP
= 2
Properties
$hasSkipped
private
bool
$hasSkipped
= false
$matrix
private
BitMatrix
$matrix
$possibleCenters
private
array<string|int, FinderPattern>
$possibleCenters
Methods
__construct()
Creates a finder that will search the image for three finder patterns.
public
__construct(BitMatrix $matrix) : mixed
Parameters
- $matrix : BitMatrix
-
image to search
find()
public
find() : array<string|int, FinderPattern>
Return values
array<string|int, FinderPattern>centerFromEnd()
Given a count of black/white/black/white/black pixels just seen and an end position, figures the location of the center of this run.
private
centerFromEnd(array<string|int, int> $stateCount, int $end) : float
Parameters
- $stateCount : array<string|int, int>
- $end : int
Return values
floatcrossCheckDiagonal()
After a vertical and horizontal scan finds a potential finder pattern, this method "cross-cross-cross-checks" by scanning down diagonally through the center of the possible finder pattern to see if the same proportion is detected.
private
crossCheckDiagonal(int $centerI, int $centerJ) : bool
Parameters
- $centerI : int
-
row where a finder pattern was detected
- $centerJ : int
-
center of the section that appears to cross a finder pattern
Return values
bool —true if proportions are withing expected limits
crossCheckHorizontal()
Like #crossCheckVertical(int, int, int, int), and in fact is basically identical, except it reads horizontally instead of vertically. This is used to cross-cross check a vertical cross-check and locate the real center of the alignment pattern.
private
crossCheckHorizontal(int $startJ, int $centerI, int $maxCount, int $originalStateCountTotal) : float|null
Parameters
- $startJ : int
- $centerI : int
- $maxCount : int
- $originalStateCountTotal : int
Tags
Return values
float|nullcrossCheckVertical()
After a horizontal scan finds a potential finder pattern, this method "cross-checks" by scanning down vertically through the center of the possible finder pattern to see if the same proportion is detected.
private
crossCheckVertical(int $startI, int $centerJ, int $maxCount, int $originalStateCountTotal) : float|null
$startI row where a finder pattern was detected $centerJ center of the section that appears to cross a finder pattern $maxCount maximum reasonable number of modules that should be observed in any reading state, based on the results of the horizontal scan $originalStateCountTotal
returns vertical center of finder pattern, or null if not found
Parameters
- $startI : int
- $centerJ : int
- $maxCount : int
- $originalStateCountTotal : int
Tags
Return values
float|nullcrossProductZ()
Returns the z component of the cross product between vectors BC and BA.
private
crossProductZ(FinderPattern $pointA, FinderPattern $pointB, FinderPattern $pointC) : float
Parameters
- $pointA : FinderPattern
- $pointB : FinderPattern
- $pointC : FinderPattern
Return values
floatdoShiftCounts2()
private
doShiftCounts2(array<string|int, int> $stateCount) : array<string|int, int>
Parameters
- $stateCount : array<string|int, int>
Return values
array<string|int, int>findRowSkip()
private
findRowSkip() : int
Return values
int —number of rows we could safely skip during scanning, based on the first two finder patterns that have been located. In some cases their position will allow us to infer that the third pattern must lie below a certain point farther down in the image.
foundPatternCross()
private
foundPatternCross(array<string|int, int> $stateCount) : bool
Parameters
- $stateCount : array<string|int, int>
Return values
boolfoundPatternDiagonal()
private
foundPatternDiagonal(array<string|int, int> $stateCount) : bool
Parameters
- $stateCount : array<string|int, int>
Return values
boolfoundPatternVariance()
private
foundPatternVariance(array<string|int, int> $stateCount, float $variance) : bool
Parameters
- $stateCount : array<string|int, int>
-
count of black/white/black/white/black pixels just read
- $variance : float
Return values
bool —true if the proportions of the counts is close enough to the 1/1/3/1/1 ratios used by finder patterns to be considered a match
getCrossCheckStateCount()
private
getCrossCheckStateCount() : array<string|int, int>
Return values
array<string|int, int>handlePossibleCenter()
This is called when a horizontal scan finds a possible alignment pattern. It will cross-check with a vertical scan, and if successful, will, ah, cross-cross-check with another horizontal scan. This is needed primarily to locate the real horizontal center of the pattern in cases of extreme skew.
private
handlePossibleCenter(array<string|int, int> $stateCount, int $i, int $j) : bool
And then we cross-cross-cross check with another diagonal scan.
If that succeeds the finder pattern location is added to a list that tracks the number of times each location has been nearly-matched as a finder pattern. Each additional find is more evidence that the location is in fact a finder pattern center
Parameters
- $stateCount : array<string|int, int>
-
reading state module counts from horizontal scan
- $i : int
-
row where finder pattern may be found
- $j : int
-
end of possible finder pattern in row
Return values
bool —if a finder pattern candidate was found this time
haveMultiplyConfirmedCenters()
private
haveMultiplyConfirmedCenters() : bool
Return values
bool —true if we have found at least 3 finder patterns that have been detected at least #CENTER_QUORUM times each, and, the estimated module size of the candidates is "pretty similar"
orderBestPatterns()
Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
private
orderBestPatterns(array<string|int, FinderPattern> $patterns) : array<string|int, FinderPattern>
Parameters
- $patterns : array<string|int, FinderPattern>
-
array of three FinderPattern to order
Return values
array<string|int, FinderPattern>selectBestPatterns()
private
selectBestPatterns() : array<string|int, FinderPattern>
Tags
Return values
array<string|int, FinderPattern> —the 3 best FinderPatterns from our list of candidates. The "best" are those that have been detected at least #CENTER_QUORUM times, and whose module size differs from the average among those patterns the least