card-recog-demo/lib/services/phash_matcher.dart

59 lines
1.4 KiB
Dart
Raw Normal View History

import '../native/phash_bindings.dart';
import '../native/phash_loader.dart';
import 'hash_library.dart';
class PhashMatch {
const PhashMatch({
required this.cardId,
required this.distance,
required this.score,
this.filename,
});
final String cardId;
final int distance;
final double score;
final String? filename;
bool get confident => score >= 75;
String? get assetPath =>
filename == null ? null : 'test_assets/$filename';
}
/// Hamming ranking over a local hash library.
class PhashMatcher {
PhashMatcher({PhashNative? native}) : _native = native ?? PhashNative();
final PhashNative _native;
static double scoreFromDistance(int distance, {int bits = kPhashBits}) {
final raw = 100.0 - (distance / bits) * 100.0;
return double.parse(raw.toStringAsFixed(2));
}
List<PhashMatch> topN(
String queryHash,
HashLibrary library, {
int n = 3,
}) {
if (library.items.isEmpty || n <= 0) return const [];
final scored = <PhashMatch>[];
for (final item in library.items) {
final distance = _native.hamming(queryHash, item.hash);
scored.add(
PhashMatch(
cardId: item.cardId,
distance: distance,
score: scoreFromDistance(distance),
filename: item.filename,
),
);
}
scored.sort((a, b) => a.distance.compareTo(b.distance));
if (scored.length <= n) return scored;
return scored.sublist(0, n);
}
}