71 lines
2.2 KiB
Dart
71 lines
2.2 KiB
Dart
|
|
import 'dart:io';
|
||
|
|
|
||
|
|
import 'package:carddex_demo/native/phash_loader.dart';
|
||
|
|
import 'package:carddex_demo/services/hash_library.dart';
|
||
|
|
import 'package:carddex_demo/services/phash_matcher.dart';
|
||
|
|
import 'package:path/path.dart' as p;
|
||
|
|
|
||
|
|
Future<void> main(List<String> args) async {
|
||
|
|
String? imagePath;
|
||
|
|
var topN = 5;
|
||
|
|
String? libPath;
|
||
|
|
|
||
|
|
for (var i = 0; i < args.length; i++) {
|
||
|
|
final a = args[i];
|
||
|
|
if ((a == '--image' || a == '-i') && i + 1 < args.length) {
|
||
|
|
imagePath = args[++i];
|
||
|
|
} else if (a == '--top' && i + 1 < args.length) {
|
||
|
|
topN = int.parse(args[++i]);
|
||
|
|
} else if (a == '--lib' && i + 1 < args.length) {
|
||
|
|
libPath = args[++i];
|
||
|
|
} else if (!a.startsWith('-') && imagePath == null) {
|
||
|
|
imagePath = a;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (imagePath == null) {
|
||
|
|
stderr.writeln(
|
||
|
|
'Usage: dart run tool/match.dart --image path/to.jpg [--top 5]',
|
||
|
|
);
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
final root = Directory.current.path;
|
||
|
|
libPath ??= _defaultLib(root);
|
||
|
|
final hashesPath = p.join(root, 'data', 'hashes.json');
|
||
|
|
|
||
|
|
if (!File(hashesPath).existsSync()) {
|
||
|
|
stderr.writeln('Missing $hashesPath — run: dart run tool/hashgen.dart');
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
final native = PhashNative(hostLibraryPath: libPath);
|
||
|
|
final matcher = PhashMatcher(native: native);
|
||
|
|
final library = await HashLibrary.loadFile(hashesPath);
|
||
|
|
|
||
|
|
final bytes = await File(imagePath).readAsBytes();
|
||
|
|
final query = native.hashFromBytes(bytes);
|
||
|
|
final matches = matcher.topN(query, library, n: topN);
|
||
|
|
|
||
|
|
stdout.writeln('query: $imagePath');
|
||
|
|
stdout.writeln('hash: $query');
|
||
|
|
stdout.writeln('library: ${library.items.length} cards');
|
||
|
|
stdout.writeln('---');
|
||
|
|
for (var i = 0; i < matches.length; i++) {
|
||
|
|
final m = matches[i];
|
||
|
|
final flag = m.confident ? 'confident' : 'low';
|
||
|
|
stdout.writeln(
|
||
|
|
'#${i + 1} ${m.cardId} dist=${m.distance} score=${m.score} ($flag)',
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
String _defaultLib(String root) {
|
||
|
|
final dylib = p.join(root, 'native', 'phash', 'build', 'libphash.dylib');
|
||
|
|
final so = p.join(root, 'native', 'phash', 'build', 'libphash.so');
|
||
|
|
if (File(dylib).existsSync()) return dylib;
|
||
|
|
if (File(so).existsSync()) return so;
|
||
|
|
stderr.writeln('libphash not found under native/phash/build/');
|
||
|
|
exit(1);
|
||
|
|
}
|