| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Imager::Search; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=pod |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
Imager::Search - Find images within other images |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use Imager::Search (); |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# Load the pattern to search for |
|
14
|
|
|
|
|
|
|
my $pattern = Imager::Search::Pattern->new( |
|
15
|
|
|
|
|
|
|
driver => 'Imager::Search::Driver::HTML24', |
|
16
|
|
|
|
|
|
|
file => 'pattern.bmp', |
|
17
|
|
|
|
|
|
|
); |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# Load the image to search in |
|
20
|
|
|
|
|
|
|
my $image = Imager::Search::Image->new( |
|
21
|
|
|
|
|
|
|
driver => 'Imager::Search::Driver::HTML24', |
|
22
|
|
|
|
|
|
|
file => 'target.bmp', |
|
23
|
|
|
|
|
|
|
); |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Execute the search |
|
26
|
|
|
|
|
|
|
my @matches = $image->find( $pattern ); |
|
27
|
|
|
|
|
|
|
print "Found " . scalar(@matches) . " matches\n"; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
The regular expression engine provided with Perl has demonstrated itself |
|
32
|
|
|
|
|
|
|
to be both fully featured and extremely fast for tasks involving searching |
|
33
|
|
|
|
|
|
|
for patterns within a string. |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
The CPAN module L has demonstrated robust functionality and |
|
36
|
|
|
|
|
|
|
excellent speed across all common operating system platforms for tasks |
|
37
|
|
|
|
|
|
|
involving working with images. |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
The goal of B takes the best features from L and the |
|
40
|
|
|
|
|
|
|
regular expression engine and combines them to produce a simple pure perl |
|
41
|
|
|
|
|
|
|
image recognition engine for systems in which the images are pixel perfect. |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
And equally importantly, B does it very very fast. |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Benchmarking a simple program that continuously monitors a 1024x768 display |
|
46
|
|
|
|
|
|
|
for a single target image on a cheap 1.5Ghtz Windows machine demonstrated |
|
47
|
|
|
|
|
|
|
a monitoring rate of 5 frames per second using the default BMP24 driver. |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
That is, 0.2 seconds to capture the screenshot, convert it into a searchable |
|
50
|
|
|
|
|
|
|
string, generate a search regexp, execute the regexp and then convert the |
|
51
|
|
|
|
|
|
|
results into match objects. |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
Finally, B itself is pure Perl, and should work quite |
|
54
|
|
|
|
|
|
|
simply on any platform that the L module supports, which at time |
|
55
|
|
|
|
|
|
|
of writing includes Windows, Mac OS X and most other forms of Unix. |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head2 Use Cases |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
L is intended to be useful for a range of tasks involving |
|
60
|
|
|
|
|
|
|
images from computing systems and the digital world in general. |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
The range of potential applications include monitoring screenshots from |
|
63
|
|
|
|
|
|
|
kiosk and advertising systems for evidence of crashes or embarrasing popup |
|
64
|
|
|
|
|
|
|
messages, automating interactions with graphics-intense desktop or website |
|
65
|
|
|
|
|
|
|
applications that would be otherwise intractable for traditional automation |
|
66
|
|
|
|
|
|
|
methods, and simple text recognition in systems with fonts that register to |
|
67
|
|
|
|
|
|
|
fixed pixel patterns. |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
For example, by storing captured image fragments of a sample set of playing |
|
70
|
|
|
|
|
|
|
cards, a program might conceptually be able to look at a solitaire-type |
|
71
|
|
|
|
|
|
|
game and establish the position and identity of all the cards on the screen, |
|
72
|
|
|
|
|
|
|
populating a model of the current game state and then allowing the |
|
73
|
|
|
|
|
|
|
automation of the playing of the game. |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
L is B intended to be useful for tasks such as facial |
|
76
|
|
|
|
|
|
|
recognition or any other tasks involving real world images. |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 Methodology |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Regular expressions are domain-specific Non-Finite Automata (NFA) |
|
81
|
|
|
|
|
|
|
programs designed to detect patterns within strings. |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
Given the problem of locating a smaller "search image" one or more |
|
84
|
|
|
|
|
|
|
times inside a larger "target image", we compile the target image into |
|
85
|
|
|
|
|
|
|
a suitable string and compile the search image into a suitable regular |
|
86
|
|
|
|
|
|
|
expression. |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
By executing the search regular expression on the target string, and |
|
89
|
|
|
|
|
|
|
translating the results of the run back into image terms, we can |
|
90
|
|
|
|
|
|
|
determine the specific location of all instances of the search image |
|
91
|
|
|
|
|
|
|
inside the target image with relative ease. |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
By decomposing the image recognition task into a regular expression task, |
|
94
|
|
|
|
|
|
|
the problem then becomes how to define a series of transforms that can |
|
95
|
|
|
|
|
|
|
generate a suitable search expression, generate a suitable target |
|
96
|
|
|
|
|
|
|
string, and derive the match locations in pixel terms from match locations |
|
97
|
|
|
|
|
|
|
in character/byte terms. |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head2 The Driver API |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
While it is fairly easy to conceive of what a potential solution might look |
|
102
|
|
|
|
|
|
|
like, implementing any solution is complicated by the need for all the code |
|
103
|
|
|
|
|
|
|
surrounding the regular expression execution to be fast as well. |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
For example, a 0.01 second regular expression search time is of no value |
|
106
|
|
|
|
|
|
|
if compiling the search and target images takes several seconds. |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
It may also be viable to achieve a shorter total processing time by |
|
109
|
|
|
|
|
|
|
storing the target image in a format which is inherently searchable |
|
110
|
|
|
|
|
|
|
(such as Windows BMP) and using slower and more complex search expression. |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Different implementations may be superior in cases where compiled search |
|
113
|
|
|
|
|
|
|
expressions are cached and applied to many target images, versus cases |
|
114
|
|
|
|
|
|
|
where compiled target images are cached and search over by many search |
|
115
|
|
|
|
|
|
|
expressions. |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
L responds to this ambiguity by not imposing a single |
|
118
|
|
|
|
|
|
|
solution, but instead defining a driver API for the transforms, so that |
|
119
|
|
|
|
|
|
|
a number of different implementations can be used with the same API in |
|
120
|
|
|
|
|
|
|
various situations. |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 The HTML24 Driver |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
A default "HTML24" implementation is provided with the module. This is a |
|
125
|
|
|
|
|
|
|
reference driver that encodes each pixel as a 24-bit HTML "#RRGGBB" colour |
|
126
|
|
|
|
|
|
|
code. |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
This driver demonstrates fast search times and a simple match resolution, |
|
129
|
|
|
|
|
|
|
but has an extremely slow method for generating the target images (as slow |
|
130
|
|
|
|
|
|
|
as 10 gigacyles for a typical 1024x768 pixel screenshot). |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
Faster drivers are currently being pursued. |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head1 USAGE |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
This new second-generation incarnation of L is still in |
|
137
|
|
|
|
|
|
|
flux, so while the API for the individual classes are relatively stable, |
|
138
|
|
|
|
|
|
|
there is not yet a top level convenience API in the B |
|
139
|
|
|
|
|
|
|
namespace itself, and the driver API is still being substantially changed |
|
140
|
|
|
|
|
|
|
in response to the differing needs of different styles of driver. |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
However a typical (if verbose) usage can be demonstrated, that should |
|
143
|
|
|
|
|
|
|
continue to work for a while... |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=head2 1. Load the Search Image |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# An image loaded from a file |
|
148
|
|
|
|
|
|
|
use Imager::Search::Image (); |
|
149
|
|
|
|
|
|
|
my $image = Imager::Search::Image->new( |
|
150
|
|
|
|
|
|
|
driver => 'Imager::Search::Driver::HTML24', |
|
151
|
|
|
|
|
|
|
file => 'target.bmp', |
|
152
|
|
|
|
|
|
|
); |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# An image captured from a screenshot |
|
155
|
|
|
|
|
|
|
use Imager::Search::Screenshot (); |
|
156
|
|
|
|
|
|
|
my $screen = Imager::Search::Screenshot->new( |
|
157
|
|
|
|
|
|
|
driver => 'Imager::Search::Driver::HTML24', |
|
158
|
|
|
|
|
|
|
); |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head2 2. Load the Search Pattern |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# A pattern loaded from a file |
|
163
|
|
|
|
|
|
|
use Imager::Search::Pattern (); |
|
164
|
|
|
|
|
|
|
my $pattern = Imager::Search::Pattern->new( |
|
165
|
|
|
|
|
|
|
driver => 'Imager::Search::Driver::HTML24', |
|
166
|
|
|
|
|
|
|
file => 'pattern.bmp', |
|
167
|
|
|
|
|
|
|
); |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head2 3. Execute the Search |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# Find the first match |
|
172
|
|
|
|
|
|
|
my $first = $image->find_first( $pattern ); |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# Find all matches |
|
175
|
|
|
|
|
|
|
my @matches = $image->find( $pattern ); |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head1 CLASSES |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
The following is the complete list of classes provided by the main |
|
180
|
|
|
|
|
|
|
B distribution. |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head2 Imager::Search::Image |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
L implements the an image that will be searched |
|
185
|
|
|
|
|
|
|
within. |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=head2 Imager::Search::Screenshot |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
L is a L |
|
190
|
|
|
|
|
|
|
subclass that captures an image from the currently active window. |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head2 Imager::Search::Pattern |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
L provides compiled search pattern objects |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=head2 Imager::Search::Match |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
L provides objects that represent locations in |
|
199
|
|
|
|
|
|
|
images where a pattern was found. |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=head2 Imager::Search::Driver |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
L is the abstract driver interface. It cannot |
|
204
|
|
|
|
|
|
|
be instantiated directly, but it describes (in both code and documentation) |
|
205
|
|
|
|
|
|
|
what any driver needs to implement. |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=head2 Imager::Search::Driver::HTML24 |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
L is an 24-bit reference driver that uses |
|
210
|
|
|
|
|
|
|
HTML colour codes (#RRGGBB) to represent each pixel. |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=head2 Imager::Search::Driver::BMP24 |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
L is a high performance 24-bit driver that |
|
215
|
|
|
|
|
|
|
uses the Windows BMP file format natively for the image string format. |
|
216
|
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=cut |
|
218
|
|
|
|
|
|
|
|
|
219
|
5
|
|
|
5
|
|
199888
|
use 5.006; |
|
|
5
|
|
|
|
|
21
|
|
|
|
5
|
|
|
|
|
393
|
|
|
220
|
5
|
|
|
5
|
|
29
|
use strict; |
|
|
5
|
|
|
|
|
11
|
|
|
|
5
|
|
|
|
|
160
|
|
|
221
|
5
|
|
|
5
|
|
28
|
use Carp (); |
|
|
5
|
|
|
|
|
20
|
|
|
|
5
|
|
|
|
|
100
|
|
|
222
|
|
|
|
|
|
|
|
|
223
|
5
|
|
|
5
|
|
34
|
use vars qw{$VERSION}; |
|
|
5
|
|
|
|
|
11
|
|
|
|
5
|
|
|
|
|
298
|
|
|
224
|
|
|
|
|
|
|
BEGIN { |
|
225
|
5
|
|
|
5
|
|
81
|
$VERSION = '1.01'; |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
|
|
228
|
5
|
|
|
5
|
|
2814
|
use Imager::Search::Pattern (); |
|
|
5
|
|
|
|
|
18
|
|
|
|
5
|
|
|
|
|
102
|
|
|
229
|
5
|
|
|
5
|
|
3275
|
use Imager::Search::Driver (); |
|
|
5
|
|
|
|
|
13
|
|
|
|
5
|
|
|
|
|
92
|
|
|
230
|
5
|
|
|
5
|
|
30
|
use Imager::Search::Match (); |
|
|
5
|
|
|
|
|
69
|
|
|
|
5
|
|
|
|
|
162
|
|
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
1; |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=pod |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=head1 SUPPORT |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
No support is available for this module. |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
However, bug reports may be filed at the following URI. |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
L |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=head1 AUTHOR |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
Adam Kennedy Eadamk@cpan.orgE |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
Copyright 2007 - 2011 Adam Kennedy. |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
This program is free software; you can redistribute |
|
253
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
The full text of the license can be found in the |
|
256
|
|
|
|
|
|
|
LICENSE file included with this module. |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=cut |