Class FinderPatternFinder
- java.lang.Object
-
- com.google.zxing.qrcode.detector.FinderPatternFinder
-
- Direct Known Subclasses:
MultiFinderPatternFinder
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.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
FinderPatternFinder.EstimatedModuleComparator
Orders byFinderPattern.getEstimatedModuleSize()
-
Field Summary
Fields Modifier and Type Field 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 Summary
Constructors Constructor Description FinderPatternFinder(BitMatrix image)
Creates a finder that will search the image for three finder patterns.FinderPatternFinder(BitMatrix image, ResultPointCallback resultPointCallback)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method 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)
LikecrossCheckVertical(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 compatibilityprivate 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.
-
-
-
Field Detail
-
CENTER_QUORUM
private static final int CENTER_QUORUM
- See Also:
- Constant Field Values
-
moduleComparator
private static final FinderPatternFinder.EstimatedModuleComparator moduleComparator
-
MIN_SKIP
protected static final int MIN_SKIP
- See Also:
- Constant Field Values
-
MAX_MODULES
protected static final int MAX_MODULES
- See Also:
- Constant Field Values
-
image
private final BitMatrix image
-
possibleCenters
private final java.util.List<FinderPattern> possibleCenters
-
hasSkipped
private boolean hasSkipped
-
crossCheckStateCount
private final int[] crossCheckStateCount
-
resultPointCallback
private final ResultPointCallback resultPointCallback
-
-
Constructor Detail
-
FinderPatternFinder
public FinderPatternFinder(BitMatrix image)
Creates a finder that will search the image for three finder patterns.
- Parameters:
image
- image to search
-
FinderPatternFinder
public FinderPatternFinder(BitMatrix image, ResultPointCallback resultPointCallback)
-
-
Method Detail
-
getImage
protected final BitMatrix getImage()
-
getPossibleCenters
protected final java.util.List<FinderPattern> getPossibleCenters()
-
find
final FinderPatternInfo find(java.util.Map<DecodeHintType,?> hints) throws NotFoundException
- Throws:
NotFoundException
-
centerFromEnd
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.
-
foundPatternCross
protected static boolean foundPatternCross(int[] stateCount)
- Parameters:
stateCount
- count of black/white/black/white/black pixels just read- Returns:
- true iff 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
-
foundPatternDiagonal
protected static boolean foundPatternDiagonal(int[] stateCount)
- Parameters:
stateCount
- count of black/white/black/white/black pixels just read- Returns:
- true iff 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 int[] getCrossCheckStateCount()
-
clearCounts
@Deprecated protected final void clearCounts(int[] counts)
Deprecated.
-
shiftCounts2
@Deprecated protected final void shiftCounts2(int[] stateCount)
Deprecated.
-
doClearCounts
protected static void doClearCounts(int[] counts)
-
doShiftCounts2
protected static void doShiftCounts2(int[] stateCount)
-
crossCheckDiagonal
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.- Parameters:
centerI
- row where a finder pattern was detectedcenterJ
- center of the section that appears to cross a finder pattern- Returns:
- true if proportions are withing expected limits
-
crossCheckVertical
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.
- Parameters:
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 scan- Returns:
- vertical center of finder pattern, or
Float.NaN
if not found
-
crossCheckHorizontal
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. This is used to cross-cross check a vertical cross check and locate the real center of the alignment pattern.
-
handlePossibleCenter
@Deprecated protected final boolean handlePossibleCenter(int[] stateCount, int i, int j, boolean pureBarcode)
Deprecated.only exists for backwards compatibility- Parameters:
stateCount
- reading state module counts from horizontal scani
- row where finder pattern may be foundj
- end of possible finder pattern in rowpureBarcode
- ignored- Returns:
- true if a finder pattern candidate was found this time
- See Also:
handlePossibleCenter(int[], int, int)
-
handlePossibleCenter
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
- Parameters:
stateCount
- reading state module counts from horizontal scani
- row where finder pattern may be foundj
- end of possible finder pattern in row- Returns:
- true if a finder pattern candidate was found this time
-
findRowSkip
private int findRowSkip()
- Returns:
- 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.
-
haveMultiplyConfirmedCenters
private boolean haveMultiplyConfirmedCenters()
- Returns:
- true iff 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"
-
squaredDistance
private static double squaredDistance(FinderPattern a, FinderPattern b)
Get square of distance between a and b.
-
selectBestPatterns
private FinderPattern[] selectBestPatterns() throws NotFoundException
- Returns:
- the 3 best
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. - Throws:
NotFoundException
- if 3 such finder patterns do not exist
-
-