Begin porting multi code finder

This commit is contained in:
Henry Schimke
2022-11-28 16:20:58 -06:00
parent 967047eb66
commit baa8406855
4 changed files with 105 additions and 124 deletions

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.multi.qrcode.detector;
import com.google.zxing.DecodeHintType;
import com.google.zxing.NotFoundException;
import com.google.zxing.ReaderException;
import com.google.zxing.RXingResultPointCallback;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DetectorRXingResult;
import com.google.zxing.qrcode.detector.Detector;
import com.google.zxing.qrcode.detector.FinderPatternInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* <p>Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code
* is rotated or skewed, or partially obscured.</p>
*
* @author Sean Owen
* @author Hannes Erven
*/
public final class MultiDetector extends Detector {
private static final DetectorRXingResult[] EMPTY_DETECTOR_RESULTS = new DetectorRXingResult[0];
public MultiDetector(BitMatrix image) {
super(image);
}
public DetectorRXingResult[] detectMulti(Map<DecodeHintType,?> hints) throws NotFoundException {
BitMatrix image = getImage();
RXingResultPointCallback resultPointCallback =
hints == null ? null : (RXingResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image, resultPointCallback);
FinderPatternInfo[] infos = finder.findMulti(hints);
if (infos.length == 0) {
throw NotFoundException.getNotFoundInstance();
}
List<DetectorRXingResult> result = new ArrayList<>();
for (FinderPatternInfo info : infos) {
try {
result.add(processFinderPatternInfo(info));
} catch (ReaderException e) {
// ignore
}
}
if (result.isEmpty()) {
return EMPTY_DETECTOR_RESULTS;
} else {
return result.toArray(EMPTY_DETECTOR_RESULTS);
}
}
}

View File

@@ -1 +1,5 @@
mod multi_detector;
pub use multi_detector::*;
mod multi_finder_pattern_finder;
pub use multi_finder_pattern_finder::*;

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use crate::{qrcode::detector::{Detector, QRCodeDetectorResult}, common::{BitMatrix, DetectorRXingResult}, DecodingHintDictionary, Exceptions, DecodeHintType};
use super::MultiFinderPatternFinder;
/**
* <p>Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code
* is rotated or skewed, or partially obscured.</p>
*
* @author Sean Owen
* @author Hannes Erven
*/
pub struct MultiDetector(Detector);
impl MultiDetector {
pub fn new(image: BitMatrix) -> Self {
Self(Detector::new(image))
}
// private static final DetectorRXingResult[] EMPTY_DETECTOR_RESULTS = new DetectorRXingResult[0];
pub fn detectMulti(&self, hints:&DecodingHintDictionary) -> Result<Vec<QRCodeDetectorResult>,Exceptions> {
let image = self.0.getImage();
let resultPointCallback =
hints.get(&DecodeHintType::NEED_RESULT_POINT_CALLBACK);
let finder = MultiFinderPatternFinder::new(image, resultPointCallback);
let infos = finder.findMulti(hints)?;
if infos.len() == 0 {
return Err(Exceptions::NotFoundException("".to_owned()))
}
let result = Vec::new();
for info in infos {
if let Ok(potential) = self.0.processFinderPatternInfo(info){
result.push(potential);
}
// try {
// result.add(processFinderPatternInfo(info));
// } catch (ReaderException e) {
// // ignore
// }
}
Ok(result)
}
}

View File

@@ -14,23 +14,27 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.zxing.multi.qrcode.detector; use crate::{qrcode::detector::{FinderPatternFinder, FinderPattern, FinderPatternInfo}, common::BitMatrix, RXingResultPointCallback, Exceptions, DecodingHintDictionary};
import com.google.zxing.DecodeHintType; // max. legal count of modules per QR code edge (177)
import com.google.zxing.NotFoundException; const MAX_MODULE_COUNT_PER_EDGE : f32 = 180_f32;
import com.google.zxing.RXingResultPoint; // min. legal count per modules per QR code edge (11)
import com.google.zxing.RXingResultPointCallback; const MIN_MODULE_COUNT_PER_EDGE : f32= 9_f32;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.detector.FinderPattern;
import com.google.zxing.qrcode.detector.FinderPatternFinder;
import com.google.zxing.qrcode.detector.FinderPatternInfo;
import java.io.Serializable;
import java.util.ArrayList; /**
import java.util.Collections; * More or less arbitrary cutoff point for determining if two finder patterns might belong
import java.util.Comparator; * to the same code if they differ less than DIFF_MODSIZE_CUTOFF_PERCENT percent in their
import java.util.List; * estimated modules sizes.
import java.util.Map; */
const DIFF_MODSIZE_CUTOFF_PERCENT : f32= 0.05_f32;
/**
* More or less arbitrary cutoff point for determining if two finder patterns might belong
* to the same code if they differ less than DIFF_MODSIZE_CUTOFF pixels/module in their
* estimated modules sizes.
*/
const DIFF_MODSIZE_CUTOFF :f32= 0.5_f32;
/** /**
* <p>This class attempts to find finder patterns in a QR Code. Finder patterns are the square * <p>This class attempts to find finder patterns in a QR Code. Finder patterns are the square
@@ -46,48 +50,32 @@ import java.util.Map;
* @author Sean Owen * @author Sean Owen
* @author Hannes Erven * @author Hannes Erven
*/ */
public final class MultiFinderPatternFinder extends FinderPatternFinder { pub struct MultiFinderPatternFinder(FinderPatternFinder);
private static final FinderPatternInfo[] EMPTY_RESULT_ARRAY = new FinderPatternInfo[0]; impl MultiFinderPatternFinder {
private static final FinderPattern[] EMPTY_FP_ARRAY = new FinderPattern[0];
private static final FinderPattern[][] EMPTY_FP_2D_ARRAY = new FinderPattern[0][]; // private static final FinderPatternInfo[] EMPTY_RESULT_ARRAY = new FinderPatternInfo[0];
// private static final FinderPattern[] EMPTY_FP_ARRAY = new FinderPattern[0];
// private static final FinderPattern[][] EMPTY_FP_2D_ARRAY = new FinderPattern[0][];
// TODO MIN_MODULE_COUNT and MAX_MODULE_COUNT would be great hints to ask the user for // TODO MIN_MODULE_COUNT and MAX_MODULE_COUNT would be great hints to ask the user for
// since it limits the number of regions to decode // since it limits the number of regions to decode
// max. legal count of modules per QR code edge (177)
private static final float MAX_MODULE_COUNT_PER_EDGE = 180;
// min. legal count per modules per QR code edge (11)
private static final float MIN_MODULE_COUNT_PER_EDGE = 9;
/**
* More or less arbitrary cutoff point for determining if two finder patterns might belong
* to the same code if they differ less than DIFF_MODSIZE_CUTOFF_PERCENT percent in their
* estimated modules sizes.
*/
private static final float DIFF_MODSIZE_CUTOFF_PERCENT = 0.05f;
/**
* More or less arbitrary cutoff point for determining if two finder patterns might belong
* to the same code if they differ less than DIFF_MODSIZE_CUTOFF pixels/module in their
* estimated modules sizes.
*/
private static final float DIFF_MODSIZE_CUTOFF = 0.5f;
/** // /**
* A comparator that orders FinderPatterns by their estimated module size. // * A comparator that orders FinderPatterns by their estimated module size.
*/ // */
private static final class ModuleSizeComparator implements Comparator<FinderPattern>, Serializable { // private static final class ModuleSizeComparator implements Comparator<FinderPattern>, Serializable {
@Override // @Override
public int compare(FinderPattern center1, FinderPattern center2) { // public int compare(FinderPattern center1, FinderPattern center2) {
float value = center2.getEstimatedModuleSize() - center1.getEstimatedModuleSize(); // float value = center2.getEstimatedModuleSize() - center1.getEstimatedModuleSize();
return value < 0.0 ? -1 : value > 0.0 ? 1 : 0; // return value < 0.0 ? -1 : value > 0.0 ? 1 : 0;
} // }
} // }
public MultiFinderPatternFinder(BitMatrix image, RXingResultPointCallback resultPointCallback) { pub fn new( image:&BitMatrix, resultPointCallback:&RXingResultPointCallback) -> Self {
super(image, resultPointCallback); Self(FinderPatternFinder::with_callback(image, resultPointCallback))
} }
/** /**
@@ -96,7 +84,7 @@ public final class MultiFinderPatternFinder extends FinderPatternFinder {
* size differs from the average among those patterns the least * size differs from the average among those patterns the least
* @throws NotFoundException if 3 such finder patterns do not exist * @throws NotFoundException if 3 such finder patterns do not exist
*/ */
private FinderPattern[][] selectMultipleBestPatterns() throws NotFoundException { fn selectMultipleBestPatterns(&self) -> Result<Vec<Vec<FinderPattern>>,Exceptions> {
List<FinderPattern> possibleCenters = new ArrayList<>(); List<FinderPattern> possibleCenters = new ArrayList<>();
for (FinderPattern fp : getPossibleCenters()) { for (FinderPattern fp : getPossibleCenters()) {
if (fp.getCount() >= 2) { if (fp.getCount() >= 2) {
@@ -220,7 +208,7 @@ public final class MultiFinderPatternFinder extends FinderPatternFinder {
throw NotFoundException.getNotFoundInstance(); throw NotFoundException.getNotFoundInstance();
} }
public FinderPatternInfo[] findMulti(Map<DecodeHintType,?> hints) throws NotFoundException { pub fn findMulti(&self, hints:&DecodingHintDictionary) -> Result<Vec<FinderPatternInfo>,Exceptions> {
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER); boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
BitMatrix image = getImage(); BitMatrix image = getImage();
int maxI = image.getHeight(); int maxI = image.getHeight();