Documentation

FinderPatternFinder
in package

FinalYes

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
author

Sean Owen

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

Properties

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

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
float

crossCheckDiagonal()

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
noinspection

DuplicatedCode

Return values
float|null

crossCheckVertical()

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
noinspection

DuplicatedCode

Return values
float|null

doShiftCounts2()

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
bool

foundPatternDiagonal()

private foundPatternDiagonal(array<string|int, int> $stateCount) : bool
Parameters
$stateCount : array<string|int, int>
Return values
bool

foundPatternVariance()

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
throws
QRCodeDetectorException

if 3 such finder patterns do not exist

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


        
On this page

Search results