mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
Begin porting multi code finder
This commit is contained in:
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1 +1,5 @@
|
|||||||
|
mod multi_detector;
|
||||||
|
pub use multi_detector::*;
|
||||||
|
|
||||||
|
mod multi_finder_pattern_finder;
|
||||||
|
pub use multi_finder_pattern_finder::*;
|
||||||
62
src/multi/qrcode/detector/multi_detector.rs
Normal file
62
src/multi/qrcode/detector/multi_detector.rs
Normal 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
Reference in New Issue
Block a user