示例#1
0
 private int findRowSkip()
 {
   if (this.possibleCenters.size() <= 1) {}
   Object localObject;
   FinderPattern localFinderPattern;
   for (;;)
   {
     return 0;
     localObject = null;
     Iterator localIterator = this.possibleCenters.iterator();
     while (localIterator.hasNext())
     {
       localFinderPattern = (FinderPattern)localIterator.next();
       if (localFinderPattern.getCount() >= 2)
       {
         if (localObject != null) {
           break label63;
         }
         localObject = localFinderPattern;
       }
     }
   }
   label63:
   this.hasSkipped = true;
   return (int)(Math.abs(localObject.getX() - localFinderPattern.getX()) - Math.abs(localObject.getY() - localFinderPattern.getY())) / 2;
 }
示例#2
0
 private boolean haveMultiplyConfirmedCenters()
 {
   int i = 0;
   float f1 = 0.0F;
   int j = this.possibleCenters.size();
   Iterator localIterator1 = this.possibleCenters.iterator();
   while (localIterator1.hasNext())
   {
     FinderPattern localFinderPattern = (FinderPattern)localIterator1.next();
     if (localFinderPattern.getCount() >= 2)
     {
       i++;
       f1 += localFinderPattern.getEstimatedModuleSize();
     }
   }
   if (i < 3) {}
   float f3;
   do
   {
     return false;
     float f2 = f1 / j;
     f3 = 0.0F;
     Iterator localIterator2 = this.possibleCenters.iterator();
     while (localIterator2.hasNext()) {
       f3 += Math.abs(((FinderPattern)localIterator2.next()).getEstimatedModuleSize() - f2);
     }
   } while (f3 > 0.05F * f1);
   return true;
 }
 /**
  * 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.
  *
  * <p>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
  *
  * @param stateCount reading state module counts from horizontal scan
  * @param i row where finder pattern may be found
  * @param j end of possible finder pattern in row
  * @return true if a finder pattern candidate was found this time
  */
 protected final boolean handlePossibleCenter(int[] stateCount, int i, int j) {
   int stateCountTotal =
       stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
   float centerJ = centerFromEnd(stateCount, j);
   float centerI = crossCheckVertical(i, (int) centerJ, stateCount[2], stateCountTotal);
   if (!Float.isNaN(centerI)) {
     // Re-cross check
     centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2], stateCountTotal);
     if (!Float.isNaN(centerJ)) {
       float estimatedModuleSize = (float) stateCountTotal / 7.0f;
       boolean found = false;
       for (int index = 0; index < possibleCenters.size(); index++) {
         FinderPattern center = possibleCenters.get(index);
         // Look for about the same center and module size:
         if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {
           possibleCenters.set(
               index, center.combineEstimate(centerI, centerJ, estimatedModuleSize));
           found = true;
           break;
         }
       }
       if (!found) {
         FinderPattern point = new FinderPattern(centerJ, centerI, estimatedModuleSize);
         possibleCenters.add(point);
         if (resultPointCallback != null) {
           resultPointCallback.foundPossibleResultPoint(point);
         }
       }
       return true;
     }
   }
   return false;
 }
示例#4
0
 public int compare(FinderPattern paramFinderPattern1, FinderPattern paramFinderPattern2)
 {
   float f1 = Math.abs(paramFinderPattern2.getEstimatedModuleSize() - this.average);
   float f2 = Math.abs(paramFinderPattern1.getEstimatedModuleSize() - this.average);
   if (f1 < f2) {
     return -1;
   }
   if (f1 == f2) {
     return 0;
   }
   return 1;
 }
 /**
  * @return 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.
  */
 private int findRowSkip() {
   int max = possibleCenters.size();
   if (max <= 1) {
     return 0;
   }
   FinderPattern firstConfirmedCenter = null;
   for (FinderPattern center : possibleCenters) {
     if (center.getCount() >= CENTER_QUORUM) {
       if (firstConfirmedCenter == null) {
         firstConfirmedCenter = center;
       } else {
         // We have two confirmed centers
         // How far down can we skip before resuming looking for the next
         // pattern? In the worst case, only the difference between the
         // difference in the x / y coordinates of the two centers.
         // This is the case where you find top left last.
         hasSkipped = true;
         return (int)
                 (Math.abs(firstConfirmedCenter.getX() - center.getX())
                     - Math.abs(firstConfirmedCenter.getY() - center.getY()))
             / 2;
       }
     }
   }
   return 0;
 }
示例#6
0
 protected final boolean handlePossibleCenter(int[] paramArrayOfInt, int paramInt1, int paramInt2)
 {
   int i = paramArrayOfInt[0] + paramArrayOfInt[1] + paramArrayOfInt[2] + paramArrayOfInt[3] + paramArrayOfInt[4];
   float f1 = centerFromEnd(paramArrayOfInt, paramInt2);
   float f2 = crossCheckVertical(paramInt1, (int)f1, paramArrayOfInt[2], i);
   if (!Float.isNaN(f2))
   {
     float f3 = crossCheckHorizontal((int)f1, (int)f2, paramArrayOfInt[2], i);
     if (!Float.isNaN(f3))
     {
       float f4 = i / 7.0F;
       for (int j = 0;; j++)
       {
         int k = this.possibleCenters.size();
         int m = 0;
         if (j < k)
         {
           FinderPattern localFinderPattern2 = (FinderPattern)this.possibleCenters.get(j);
           if (localFinderPattern2.aboutEquals(f4, f2, f3))
           {
             this.possibleCenters.set(j, localFinderPattern2.combineEstimate(f2, f3, f4));
             m = 1;
           }
         }
         else
         {
           if (m == 0)
           {
             FinderPattern localFinderPattern1 = new FinderPattern(f3, f2, f4);
             this.possibleCenters.add(localFinderPattern1);
             if (this.resultPointCallback != null) {
               this.resultPointCallback.foundPossibleResultPoint(localFinderPattern1);
             }
           }
           return true;
         }
       }
     }
   }
   return false;
 }
 /**
  * @return true iff we have found at least 3 finder patterns that have been detected at least
  *     {@link #CENTER_QUORUM} times each, and, the estimated module size of the candidates is
  *     "pretty similar"
  */
 private boolean haveMultiplyConfirmedCenters() {
   int confirmedCount = 0;
   float totalModuleSize = 0.0f;
   int max = possibleCenters.size();
   for (FinderPattern pattern : possibleCenters) {
     if (pattern.getCount() >= CENTER_QUORUM) {
       confirmedCount++;
       totalModuleSize += pattern.getEstimatedModuleSize();
     }
   }
   if (confirmedCount < 3) {
     return false;
   }
   // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
   // and that we need to keep looking. We detect this by asking if the estimated module sizes
   // vary too much. We arbitrarily say that when the total deviation from average exceeds
   // 5% of the total module size estimates, it's too much.
   float average = totalModuleSize / (float) max;
   float totalDeviation = 0.0f;
   for (FinderPattern pattern : possibleCenters) {
     totalDeviation += Math.abs(pattern.getEstimatedModuleSize() - average);
   }
   return totalDeviation <= 0.05f * totalModuleSize;
 }
 @Override
 public int compare(FinderPattern center1, FinderPattern center2) {
   if (center2.getCount() == center1.getCount()) {
     float dA = Math.abs(center2.getEstimatedModuleSize() - average);
     float dB = Math.abs(center1.getEstimatedModuleSize() - average);
     return dA < dB ? 1 : dA == dB ? 0 : -1;
   } else {
     return center2.getCount() - center1.getCount();
   }
 }
  /**
   * @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are those
   *     that have been detected at least {@link #CENTER_QUORUM} times, and whose module size
   *     differs from the average among those patterns the least
   * @throws NotFoundException if 3 such finder patterns do not exist
   */
  private FinderPattern[] selectBestPatterns() throws NotFoundException {

    int startSize = possibleCenters.size();
    if (startSize < 3) {
      // Couldn't find enough finder patterns
      throw NotFoundException.getNotFoundInstance();
    }

    // Filter outlier possibilities whose module size is too different
    if (startSize > 3) {
      // But we can only afford to do so if we have at least 4 possibilities to choose from
      float totalModuleSize = 0.0f;
      float square = 0.0f;
      for (FinderPattern center : possibleCenters) {
        float size = center.getEstimatedModuleSize();
        totalModuleSize += size;
        square += size * size;
      }
      float average = totalModuleSize / (float) startSize;
      float stdDev = (float) Math.sqrt(square / startSize - average * average);

      Collections.sort(possibleCenters, new FurthestFromAverageComparator(average));

      float limit = Math.max(0.2f * average, stdDev);

      for (int i = 0; i < possibleCenters.size() && possibleCenters.size() > 3; i++) {
        FinderPattern pattern = possibleCenters.get(i);
        if (Math.abs(pattern.getEstimatedModuleSize() - average) > limit) {
          possibleCenters.remove(i);
          i--;
        }
      }
    }

    if (possibleCenters.size() > 3) {
      // Throw away all but those first size candidate points we found.

      float totalModuleSize = 0.0f;
      for (FinderPattern possibleCenter : possibleCenters) {
        totalModuleSize += possibleCenter.getEstimatedModuleSize();
      }

      float average = totalModuleSize / (float) possibleCenters.size();

      Collections.sort(possibleCenters, new CenterComparator(average));

      possibleCenters.subList(3, possibleCenters.size()).clear();
    }

    return new FinderPattern[] {
      possibleCenters.get(0), possibleCenters.get(1), possibleCenters.get(2)
    };
  }
 protected final DetectorResult a(FinderPatternInfo paramFinderPatternInfo)
 {
   FinderPattern localFinderPattern1 = paramFinderPatternInfo.b();
   FinderPattern localFinderPattern2 = paramFinderPatternInfo.c();
   FinderPattern localFinderPattern3 = paramFinderPatternInfo.a();
   float f1 = a(localFinderPattern1, localFinderPattern2, localFinderPattern3);
   if (f1 < 1.0F)
     throw NotFoundException.a();
   int i = a(localFinderPattern1, localFinderPattern2, localFinderPattern3, f1);
   Version localVersion = Version.a(i);
   int j = -7 + localVersion.d();
   int k = localVersion.b().length;
   Object localObject = null;
   int m;
   int n;
   int i1;
   float f5;
   if (k > 0)
   {
     float f2 = localFinderPattern2.a() - localFinderPattern1.a() + localFinderPattern3.a();
     float f3 = localFinderPattern2.b() - localFinderPattern1.b() + localFinderPattern3.b();
     float f4 = 1.0F - 3.0F / j;
     m = (int)(localFinderPattern1.a() + f4 * (f2 - localFinderPattern1.a()));
     n = (int)(localFinderPattern1.b() + f4 * (f3 - localFinderPattern1.b()));
     i1 = 4;
     localObject = null;
     if (i1 <= 16)
       f5 = i1;
   }
   while (true)
   {
     try
     {
       AlignmentPattern localAlignmentPattern = a(f1, m, n, f5);
       localObject = localAlignmentPattern;
       PerspectiveTransform localPerspectiveTransform = a(localFinderPattern1, localFinderPattern2, localFinderPattern3, localObject, i);
       BitMatrix localBitMatrix = a(this.a, localPerspectiveTransform, i);
       if (localObject != null)
         break label270;
       arrayOfResultPoint = new ResultPoint[] { localFinderPattern3, localFinderPattern1, localFinderPattern2 };
       return new DetectorResult(localBitMatrix, arrayOfResultPoint);
     }
     catch (NotFoundException localNotFoundException)
     {
       i1 <<= 1;
     }
     break;
     label270: ResultPoint[] arrayOfResultPoint = { localFinderPattern3, localFinderPattern1, localFinderPattern2, localObject };
   }
 }
 @Override
 public int compare(FinderPattern center1, FinderPattern center2) {
   float dA = Math.abs(center2.getEstimatedModuleSize() - average);
   float dB = Math.abs(center1.getEstimatedModuleSize() - average);
   return dA < dB ? -1 : dA == dB ? 0 : 1;
 }