forked from os-autoinst/os-autoinst
-
Notifications
You must be signed in to change notification settings - Fork 0
/
imgsearch
executable file
·95 lines (80 loc) · 3.06 KB
/
imgsearch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/perl -w
# Copyright 2021 SUSE LLC
# SPDX-License-Identifier: GPL-2.0-or-later
#
use Mojo::Base -strict, -signatures;
use Mojo::JSON qw(encode_json);
use Mojo::Log;
use Mojo::Util qw(getopt);
use FindBin '$Bin';
use lib "$Bin";
use cv;
use needle;
# define a basic needle package; normally `needle` should inherit from this package
{
package basic_needle;
use base 'needle';
use Mojo::File qw(path);
sub new ($classname, $image_path, $match_level, $margin) {
my $name = path($image_path)->basename;
my $image = tinycv::read $image_path;
my %area = (type => 'match', match => $match_level, margin => $margin,
xpos => 0, ypos => 0, width => $image->xres, height => $image->yres,
img => $image);
my $self = {name => $name, png => $image_path, area => [\%area]};
bless $self, $classname;
$self->register;
return $self;
}
sub get_image ($self, $area = undef) { ($area // $self->{area}->[0])->{img} }
sub from_paths ($needle_paths, @args) { [map { basic_needle->new($_, @args) } @$needle_paths] }
}
sub usage ($r) {
print "imgsearch [options]
options:
--needle-images specifies images to look for
--haystack-images specifies images to look in
--verbose enables debug output
--help Show this help
example:
imagesearch \
--needle-images logo1.png logo2.png \
--haystack-images asset.png screenshot.png
";
exit $r;
}
getopt 'needle-images=s@{1,}' => \my @needle_image_paths,
'haystack-images=s@{1,}' => \my @image_paths,
'match-level=f' => \my $match_level,
'margin=f' => \my $margin,
'threshold=f' => \my $threshold,
'search-ratio=f' => \my $search_ratio,
'v|verbose' => \my $verbose,
'h|help' => \my $help;
usage(0) if $help;
usage(1) unless @needle_image_paths && @image_paths;
# stop opencv logging messages polluting stdout
$ENV{'OPENCV_LOG_LEVEL'} ||= 'SILENT';
# initialize logging, tinycv and parameters
my $log = Mojo::Log->new;
$log->level($verbose ? 'debug' : 'info');
$log->debug('Loading tinycv');
cv::init;
require tinycv;
$match_level //= 80; # the similarity level required to consider a finding a match (unit: percent)
$margin //= 1_000_000; # very high value to search within full image by default (unit: pixel)
$search_ratio //= 0; # set to zero to disable unwanted computation of margin (which assumes an image width of 1024 px)
$threshold //= 0.0; # subtracted from each area's match level; just keep at zero here
$log->debug("Martch-level: $match_level, margin: $margin, threshold: $threshold, search ratio: $search_ratio");
# load needles
$log->info('Loading needles');
my $needles = basic_needle::from_paths(\@needle_image_paths, $match_level, $margin);
# search needles in images
my %results = map {
my $image_path = $_;
$log->info("Searching $image_path");
my $image = tinycv::read $image_path;
my ($match, $candidates) = $image->search($needles, $threshold, $search_ratio);
($image_path => {match => $match, candidates => $candidates});
} @image_paths;
print encode_json(\%results);