public class FinderPatternFinder
extends java.lang.Object
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.
Modifier and Type | Class and Description |
---|---|
private static class |
FinderPatternFinder.EstimatedModuleComparator
Orders by
FinderPattern.getEstimatedModuleSize() |
Modifier and Type | Field and Description |
---|---|
private static int |
CENTER_QUORUM |
private int[] |
crossCheckStateCount |
private boolean |
hasSkipped |
private BitMatrix |
image |
protected static int |
MAX_MODULES |
protected static int |
MIN_SKIP |
private static FinderPatternFinder.EstimatedModuleComparator |
moduleComparator |
private java.util.List<FinderPattern> |
possibleCenters |
private ResultPointCallback |
resultPointCallback |
Constructor and Description |
---|
FinderPatternFinder(BitMatrix image)
Creates a finder that will search the image for three finder patterns.
|
FinderPatternFinder(BitMatrix image,
ResultPointCallback resultPointCallback) |
Modifier and Type | Method and Description |
---|---|
private static float |
centerFromEnd(int[] stateCount,
int end)
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.
|
protected void |
clearCounts(int[] counts)
Deprecated.
|
private boolean |
crossCheckDiagonal(int centerI,
int centerJ)
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 float |
crossCheckHorizontal(int startJ,
int centerI,
int maxCount,
int originalStateCountTotal)
Like
crossCheckVertical(int, int, int, int) , and in fact is basically identical,
except it reads horizontally instead of vertically. |
private float |
crossCheckVertical(int startI,
int centerJ,
int maxCount,
int originalStateCountTotal)
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.
|
protected static void |
doClearCounts(int[] counts) |
protected static void |
doShiftCounts2(int[] stateCount) |
(package private) FinderPatternInfo |
find(java.util.Map<DecodeHintType,?> hints) |
private int |
findRowSkip() |
protected static boolean |
foundPatternCross(int[] stateCount) |
protected static boolean |
foundPatternDiagonal(int[] stateCount) |
private int[] |
getCrossCheckStateCount() |
protected BitMatrix |
getImage() |
protected java.util.List<FinderPattern> |
getPossibleCenters() |
protected boolean |
handlePossibleCenter(int[] stateCount,
int i,
int j)
This is called when a horizontal scan finds a possible alignment pattern.
|
protected boolean |
handlePossibleCenter(int[] stateCount,
int i,
int j,
boolean pureBarcode)
Deprecated.
only exists for backwards compatibility
|
private boolean |
haveMultiplyConfirmedCenters() |
private FinderPattern[] |
selectBestPatterns() |
protected void |
shiftCounts2(int[] stateCount)
Deprecated.
|
private static double |
squaredDistance(FinderPattern a,
FinderPattern b)
Get square of distance between a and b.
|
private static final int CENTER_QUORUM
private static final FinderPatternFinder.EstimatedModuleComparator moduleComparator
protected static final int MIN_SKIP
protected static final int MAX_MODULES
private final BitMatrix image
private final java.util.List<FinderPattern> possibleCenters
private boolean hasSkipped
private final int[] crossCheckStateCount
private final ResultPointCallback resultPointCallback
public FinderPatternFinder(BitMatrix image)
Creates a finder that will search the image for three finder patterns.
image
- image to searchpublic FinderPatternFinder(BitMatrix image, ResultPointCallback resultPointCallback)
protected final BitMatrix getImage()
protected final java.util.List<FinderPattern> getPossibleCenters()
final FinderPatternInfo find(java.util.Map<DecodeHintType,?> hints) throws NotFoundException
NotFoundException
private static float centerFromEnd(int[] stateCount, int end)
protected static boolean foundPatternCross(int[] stateCount)
stateCount
- count of black/white/black/white/black pixels just readprotected static boolean foundPatternDiagonal(int[] stateCount)
stateCount
- count of black/white/black/white/black pixels just readprivate int[] getCrossCheckStateCount()
@Deprecated protected final void clearCounts(int[] counts)
@Deprecated protected final void shiftCounts2(int[] stateCount)
protected static void doClearCounts(int[] counts)
protected static void doShiftCounts2(int[] stateCount)
private boolean crossCheckDiagonal(int centerI, int centerJ)
centerI
- row where a finder pattern was detectedcenterJ
- center of the section that appears to cross a finder patternprivate float crossCheckVertical(int startI, int centerJ, int maxCount, int originalStateCountTotal)
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.
startI
- row where a finder pattern was detectedcenterJ
- center of the section that appears to cross a finder patternmaxCount
- maximum reasonable number of modules that should be
observed in any reading state, based on the results of the horizontal scanFloat.NaN
if not foundprivate float crossCheckHorizontal(int startJ, int centerI, int maxCount, int originalStateCountTotal)
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.
@Deprecated protected final boolean handlePossibleCenter(int[] stateCount, int i, int j, boolean pureBarcode)
stateCount
- reading state module counts from horizontal scani
- row where finder pattern may be foundj
- end of possible finder pattern in rowpureBarcode
- ignoredhandlePossibleCenter(int[], int, int)
protected final boolean handlePossibleCenter(int[] stateCount, int i, int j)
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. 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
stateCount
- reading state module counts from horizontal scani
- row where finder pattern may be foundj
- end of possible finder pattern in rowprivate int findRowSkip()
private boolean haveMultiplyConfirmedCenters()
CENTER_QUORUM
times each, and, the estimated module size of the
candidates is "pretty similar"private static double squaredDistance(FinderPattern a, FinderPattern b)
private FinderPattern[] selectBestPatterns() throws NotFoundException
FinderPattern
s from our list of candidates. The "best" are
those have similar module size and form a shape closer to a isosceles right triangle.NotFoundException
- if 3 such finder patterns do not exist