mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Enhance GenericResultPoint and move some logic out of qrcode packages for reuse with datamatrix soon
git-svn-id: https://zxing.googlecode.com/svn/trunk@522 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
81ef86b634
commit
5c8b0558e1
|
@ -43,7 +43,7 @@ public final class GenericResultPoint implements ResultPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuffer result = new StringBuffer(25);
|
||||||
result.append('(');
|
result.append('(');
|
||||||
result.append(posX);
|
result.append(posX);
|
||||||
result.append(',');
|
result.append(',');
|
||||||
|
@ -52,4 +52,66 @@ public final class GenericResultPoint implements ResultPoint {
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other instanceof GenericResultPoint) {
|
||||||
|
GenericResultPoint otherPoint = (GenericResultPoint) other;
|
||||||
|
return posX == otherPoint.posX && posY == otherPoint.posY;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return 31 * Float.floatToIntBits(posX) + Float.floatToIntBits(posY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
|
||||||
|
* BC < AC and the angle between BC and BA is less than 180 degrees.
|
||||||
|
*/
|
||||||
|
public static void orderBestPatterns(ResultPoint[] patterns) {
|
||||||
|
|
||||||
|
// Find distances between pattern centers
|
||||||
|
float zeroOneDistance = distance(patterns[0], patterns[1]);
|
||||||
|
float oneTwoDistance = distance(patterns[1], patterns[2]);
|
||||||
|
float zeroTwoDistance = distance(patterns[0], patterns[2]);
|
||||||
|
|
||||||
|
ResultPoint pointA, pointB, pointC;
|
||||||
|
// Assume one closest to other two is B; A and C will just be guesses at first
|
||||||
|
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
|
||||||
|
pointB = patterns[0];
|
||||||
|
pointA = patterns[1];
|
||||||
|
pointC = patterns[2];
|
||||||
|
} else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
|
||||||
|
pointB = patterns[1];
|
||||||
|
pointA = patterns[0];
|
||||||
|
pointC = patterns[2];
|
||||||
|
} else {
|
||||||
|
pointB = patterns[2];
|
||||||
|
pointA = patterns[0];
|
||||||
|
pointC = patterns[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use cross product to figure out whether A and C are correct or flipped.
|
||||||
|
if ((pointC.getY() - pointB.getY()) * (pointA.getX() - pointB.getX()) >
|
||||||
|
(pointC.getX() - pointB.getX()) * (pointA.getY() - pointB.getY())) {
|
||||||
|
ResultPoint temp = pointA;
|
||||||
|
pointA = pointC;
|
||||||
|
pointC = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
patterns[0] = pointA;
|
||||||
|
patterns[1] = pointB;
|
||||||
|
patterns[2] = pointC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return distance between two points
|
||||||
|
*/
|
||||||
|
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
|
||||||
|
float xDiff = pattern1.getX() - pattern2.getX();
|
||||||
|
float yDiff = pattern1.getY() - pattern2.getY();
|
||||||
|
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,6 +22,7 @@ import com.google.zxing.ReaderException;
|
||||||
import com.google.zxing.ResultPoint;
|
import com.google.zxing.ResultPoint;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
import com.google.zxing.common.DetectorResult;
|
import com.google.zxing.common.DetectorResult;
|
||||||
|
import com.google.zxing.common.GenericResultPoint;
|
||||||
import com.google.zxing.common.GridSampler;
|
import com.google.zxing.common.GridSampler;
|
||||||
import com.google.zxing.qrcode.decoder.Version;
|
import com.google.zxing.qrcode.decoder.Version;
|
||||||
|
|
||||||
|
@ -172,8 +173,8 @@ public final class Detector {
|
||||||
ResultPoint topRight,
|
ResultPoint topRight,
|
||||||
ResultPoint bottomLeft,
|
ResultPoint bottomLeft,
|
||||||
float moduleSize) throws ReaderException {
|
float moduleSize) throws ReaderException {
|
||||||
int tltrCentersDimension = round(FinderPatternFinder.distance(topLeft, topRight) / moduleSize);
|
int tltrCentersDimension = round(GenericResultPoint.distance(topLeft, topRight) / moduleSize);
|
||||||
int tlblCentersDimension = round(FinderPatternFinder.distance(topLeft, bottomLeft) / moduleSize);
|
int tlblCentersDimension = round(GenericResultPoint.distance(topLeft, bottomLeft) / moduleSize);
|
||||||
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
||||||
switch (dimension & 0x03) { // mod 4
|
switch (dimension & 0x03) { // mod 4
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -19,10 +19,10 @@ package com.google.zxing.qrcode.detector;
|
||||||
import com.google.zxing.DecodeHintType;
|
import com.google.zxing.DecodeHintType;
|
||||||
import com.google.zxing.MonochromeBitmapSource;
|
import com.google.zxing.MonochromeBitmapSource;
|
||||||
import com.google.zxing.ReaderException;
|
import com.google.zxing.ReaderException;
|
||||||
import com.google.zxing.ResultPoint;
|
|
||||||
import com.google.zxing.common.BitArray;
|
import com.google.zxing.common.BitArray;
|
||||||
import com.google.zxing.common.Collections;
|
import com.google.zxing.common.Collections;
|
||||||
import com.google.zxing.common.Comparator;
|
import com.google.zxing.common.Comparator;
|
||||||
|
import com.google.zxing.common.GenericResultPoint;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
@ -157,7 +157,7 @@ final class FinderPatternFinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
FinderPattern[] patternInfo = selectBestPatterns();
|
FinderPattern[] patternInfo = selectBestPatterns();
|
||||||
patternInfo = orderBestPatterns(patternInfo);
|
GenericResultPoint.orderBestPatterns(patternInfo);
|
||||||
|
|
||||||
return new FinderPatternInfo(patternInfo);
|
return new FinderPatternInfo(patternInfo);
|
||||||
}
|
}
|
||||||
|
@ -503,63 +503,6 @@ final class FinderPatternFinder {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Having found three "best" finder patterns we need to decide which is the top-left, top-right,
|
|
||||||
* bottom-left. We assume that the one closest to the other two is the top-left one; this is not
|
|
||||||
* strictly true (imagine extreme perspective distortion) but for the moment is a serviceable assumption.
|
|
||||||
* Lastly we sort top-right from bottom-left by figuring out orientation from vector cross products.</p>
|
|
||||||
*
|
|
||||||
* @param patterns three best {@link FinderPattern}s
|
|
||||||
* @return same {@link FinderPattern}s ordered bottom-left, top-left, top-right
|
|
||||||
*/
|
|
||||||
private static FinderPattern[] orderBestPatterns(FinderPattern[] patterns) {
|
|
||||||
|
|
||||||
// Find distances between pattern centers
|
|
||||||
float abDistance = distance(patterns[0], patterns[1]);
|
|
||||||
float bcDistance = distance(patterns[1], patterns[2]);
|
|
||||||
float acDistance = distance(patterns[0], patterns[2]);
|
|
||||||
|
|
||||||
FinderPattern topLeft;
|
|
||||||
FinderPattern topRight;
|
|
||||||
FinderPattern bottomLeft;
|
|
||||||
// Assume one closest to other two is top left;
|
|
||||||
// topRight and bottomLeft will just be guesses below at first
|
|
||||||
if (bcDistance >= abDistance && bcDistance >= acDistance) {
|
|
||||||
topLeft = patterns[0];
|
|
||||||
topRight = patterns[1];
|
|
||||||
bottomLeft = patterns[2];
|
|
||||||
} else if (acDistance >= bcDistance && acDistance >= abDistance) {
|
|
||||||
topLeft = patterns[1];
|
|
||||||
topRight = patterns[0];
|
|
||||||
bottomLeft = patterns[2];
|
|
||||||
} else {
|
|
||||||
topLeft = patterns[2];
|
|
||||||
topRight = patterns[0];
|
|
||||||
bottomLeft = patterns[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use cross product to figure out which of other1/2 is the bottom left
|
|
||||||
// pattern. The vector "top-left -> bottom-left" x "top-left -> top-right"
|
|
||||||
// should yield a vector with positive z component
|
|
||||||
if ((bottomLeft.getY() - topLeft.getY()) * (topRight.getX() - topLeft.getX()) <
|
|
||||||
(bottomLeft.getX() - topLeft.getX()) * (topRight.getY() - topLeft.getY())) {
|
|
||||||
FinderPattern temp = topRight;
|
|
||||||
topRight = bottomLeft;
|
|
||||||
bottomLeft = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FinderPattern[]{bottomLeft, topLeft, topRight};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return distance between two points
|
|
||||||
*/
|
|
||||||
static float distance(ResultPoint pattern1, ResultPoint pattern2) {
|
|
||||||
float xDiff = pattern1.getX() - pattern2.getX();
|
|
||||||
float yDiff = pattern1.getY() - pattern2.getY();
|
|
||||||
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Orders by {@link FinderPattern#getCount()}, descending.</p>
|
* <p>Orders by {@link FinderPattern#getCount()}, descending.</p>
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue