File Coverage

imgsearch
Criterion Covered Total %
statement 84 85 98.8
total 84 85 98.8


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