This file is indexed.

/usr/share/pyshared/gamera/plugins/features.py is in python-gamera 3.3.3-2ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
#
# Copyright (C) 2001-2005 Ichiro Fujinaga, Michael Droettboom, Karl MacMillan
#               2009-2010 Christoph Dalitz
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

import array
from gamera.plugin import *
import _features

class Feature(PluginFunction):
    self_type = ImageType([ONEBIT])
    return_type = FloatVector(length=1)
    feature_function = True
    doc_examples = [(ONEBIT,)]

class black_area(Feature):
    """
    The simplest of all feature-generating functions, ``black_area``
    simply returns the number of black pixels.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |       |     X    |   X    |
    +-------+----------+--------+
    
    .. warning:: This feature is not scale invariant.
    """
    pass

class moments(Feature):
    """
    Returns *moments* of the image.

    The first two elements of the returned ``FloatVector`` are the 
    center of gravity on *x* and *y* axis normalized by width and height,
    respectively. The following seven entries are the 
    *normalized central moments* (*u20,u02,u11,u30,u12,u21,u03*). For their
    definition, see Gonzalez, Woods: \"Digital Image Processing\",
    Prentice Hall, second edition (2002).

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |        |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=9)

class nholes(Feature):
    """
    Computes for each row or column the average number of white runs not
	touching the border. From these values, the average over all rows and
	all columns is returned.

    The elements of the returned ``FloatVector`` are:

    0. vertical
    1. horizontal

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |   X    |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=2)

class nholes_extended(Feature):
    """
    Divides the image into four strips and then does a nholes_
    analysis on each of those strips. This is first done vertically
    and then horizontally, resulting in a total of eight feature values.

    The elements of the returned ``FloatVector`` are:

    0 - 3
      vertical ``nholes`` for each of the strips in order left to right.
    4 - 7
      horizonal ``nholes`` for each of the strips in order top to bottom.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |        |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=8)

class volume(Feature):
    """
    The percentage of black pixels within the rectangular bounding box
    of the image.  Result in range (0, 1].

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |   X    |
    +-------+----------+--------+
    """
    pass

class area(Feature):
    """
    The area of the bounding box (i.e. *nrows* * *ncols*).

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |       |          |   X    |
    +-------+----------+--------+
    """
    pass

class aspect_ratio(Feature):
    """
    The aspect ratio of the bounding box (i.e. *ncols* / *nrows*).

    This feature is scale invariant.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |   X    |
    +-------+----------+--------+
    """
    pass
    
class nrows_feature(Feature):
    """
    Simply the number of rows. As this feature is *not* scale
    invariant, it is helpful for distinguishing similar symbols of
    different size.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |       |          |   X    |
    +-------+----------+--------+
    """
    pass

class ncols_feature(Feature):
    """
    Simply the number of cols. As this feature is *not* scale
    invariant, it is helpful for distinguishing similar symbols of
    different size.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |       |          |   X    |
    +-------+----------+--------+
    """
    pass

class compactness(Feature):
    """
    Compactness is the volume to surface ratio. Highly ornate connected
    components have a low compactness, whereas a perfect circle has a 
    high compactness. The present implementation of this feature in
    Gamera does however not return the compactness, but its *inverse*,
    i.e. the surface to volume ratio.

    Since this function requires allocation and deallocation of
    memory, it is relatively slow.  However, it has proven to be a
    very useful feature in many cases.

    This feature is not scale invariant, because, as
    the image is scaled by *a*, the surface increases proportional to *a*
    while the volume grows with *a^2*.
    This is currently not corrected for.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |       |    X     |   X    |
    +-------+----------+--------+
    """
    pass
    
class volume16regions(Feature):
    """
    Divides the image into a 4 x 4 grid of 16 regions and calculates
    the volume within each. This feature is also known as \"zoning\" method.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |        |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=16)

class volume64regions(Feature):
    """
    Divides the image into a 8 x 8 grid of 64 regions and calculates
    the volume within each. This feature is also known as \"zoning\" method.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |        |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=64)

class zernike_moments(Feature):
    """
    Computes the absolute values of the Normalized Zernike Moments up to
    order six.

    Zernike moments are the scalar product in the complex L2
    Hilbert space between the image and the complex Zernike polynomials.
    This results in complex values, the absolute values of which are
    invariant under image rotation and reflection. To make them additionally
    scale invariant, different normalization schemes have been suggested.
    The present implementation normalizes the Zernike moments by
    division with the zeroeth geometric moment *m00*, which results
    in an approximate scale invariance according to
    S. Belkasim, E. Hassan, T. Obeidi: \"Explicit invariance of Cartesian
    Zernike moments.\" Pattern Recognition Letters 28, pp. 1969-1980 (2007)

    The return values are the absolute values of
    *A20, A22, A31, A33, A40, A42, A44, A51, A53, A54, A60, A62, A64, A66*.
    The moments *A00* and *A11* are not computed because these are constant
    under the used normalization scheme.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |    X     |   X    |
    +-------+----------+--------+
    """
    author = "Robert Butz and Christoph Dalitz"
    return_type = FloatVector(length=14)

class skeleton_features(Feature):
    """
    Generates a number of features based on the skeleton of an image.
    First, the image in skeletonized using the Lee and Chen algorithm,
    which guarantees that the pixels of the resulting skeleton are
    never more than 4-connected.  Then, this skeleton is analysed for
    a number of properties:
    
    0. Number of X joints (4-connected pixels)
    1. Number of T joints (3-connected pixels)
    2. Average number of bend points (pixels which do not form a horizontal or
       vertical line with its neighbors)
    3. Number of end points (1-connected pixels)
    4. Number of *x*-axis crossings with respect to the *x*-axis through the center of mass
    5. Number of *y*-axis crossings with respect to the *y*-axis through the center of mass

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |   X    |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=6)

class top_bottom(Feature):
    """
    Features useful only for segmentation-free analysis.  Currently,
    the first feature is the first row containing a black pixel, and
    the second feature is the last row containing a black pixel.

    +---------------------------+
    | **Invariant to:**         |  
    +-------+----------+--------+
    | scale | rotation | mirror | 
    +-------+----------+--------+
    |   X   |          |   X    |
    +-------+----------+--------+
    """
    return_type = FloatVector(length=2)

class generate_features(PluginFunction):
    """
    Generates features for the image by calling a number of feature
    functions and storing the results in the image's ``features``
    member variable (a Python ``array``).
    
    *features*
      Optional.  A list of feature function names.  If not given, the
      previously set feature functions will be used.  If none were
      previously given, all available feature functions will be used.
      Using all feature functions can also be forced by passing
      ``'all'``.

    .. warning:: For efficiency, if the given feature functions match
       those that have been already generated for the image, the
       features are *not* recalculated.  If you want to force
       recalculation, pass the optional argument ``force=True``.
    """
    category = "Utility"
    pure_python = True
    self_type = ImageType([ONEBIT])
    args = Args([Class('features', list), Check('force')])
    return_type = None
    cache = {}
    def __call__(self, features=None, force=False):
      if features is None:
         features = self.get_feature_functions()
      if self.feature_functions == features and not force:
         return
      self.feature_functions = features
      features, num_features = features
      if len(self.features) != num_features:
          if not generate_features.cache.has_key(num_features):
              generate_features.cache[num_features] = [0] * num_features
          self.features = array.array('d', generate_features.cache[num_features])
      offset = 0
      for name, function in features:
          function.__call__(self, offset)
          offset += function.return_type.length
    __call__ = staticmethod(__call__)

class FeaturesModule(PluginModule):
    category = "Features"
    cpp_headers=["features.hpp"]
    functions = [black_area, moments, nholes,
                 nholes_extended, volume, area,
                 aspect_ratio, nrows_feature, ncols_feature, compactness,
                 volume16regions, volume64regions,
                 generate_features, zernike_moments,
                 skeleton_features, top_bottom]
    author = "Michael Droettboom and Karl MacMillan"
    url = "http://gamera.sourceforge.net/"
module = FeaturesModule()

def get_features_length(features):
    """
    Given a list of feature functions return the number of features
    that will be generated. This function is necessary because each
    features 'function' can return multiple individual float values.
    """
    from gamera import core
    ff = core.ImageBase.get_feature_functions(features)
    return ff[1]

def generate_features_list(list, features='all'):
   """
   Generate features on a list of images.

   *features*
     Follows the same rules as for generate_features_.
   """
   from gamera import core, util
   ff = core.Image.get_feature_functions(features)
   progress = util.ProgressFactory("Generating features...", len(list) / 10)
   try:
      for i, glyph in enumerate(list):
         glyph.generate_features(ff)
         if i % 10 == 0:
             progress.step()
   finally:
       progress.kill()

generate_features = generate_features()

del Feature