ruby-vips 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +31 -0
- data/LICENSE +20 -0
- data/README.md +96 -0
- data/TODO +18 -0
- data/ext/extconf.rb +10 -0
- data/ext/header.c +440 -0
- data/ext/header.h +8 -0
- data/ext/image.c +639 -0
- data/ext/image.h +71 -0
- data/ext/image_arithmetic.c +940 -0
- data/ext/image_arithmetic.h +38 -0
- data/ext/image_boolean.c +302 -0
- data/ext/image_boolean.h +8 -0
- data/ext/image_colour.c +593 -0
- data/ext/image_colour.h +36 -0
- data/ext/image_conversion.c +863 -0
- data/ext/image_conversion.h +37 -0
- data/ext/image_convolution.c +371 -0
- data/ext/image_convolution.h +13 -0
- data/ext/image_freq_filt.c +742 -0
- data/ext/image_freq_filt.h +27 -0
- data/ext/image_histograms_lut.c +646 -0
- data/ext/image_histograms_lut.h +28 -0
- data/ext/image_morphology.c +330 -0
- data/ext/image_morphology.h +13 -0
- data/ext/image_mosaicing.c +556 -0
- data/ext/image_mosaicing.h +14 -0
- data/ext/image_relational.c +386 -0
- data/ext/image_relational.h +8 -0
- data/ext/image_resample.c +253 -0
- data/ext/image_resample.h +9 -0
- data/ext/interpolator.c +106 -0
- data/ext/interpolator.h +6 -0
- data/ext/mask.c +349 -0
- data/ext/mask.h +17 -0
- data/ext/reader.c +315 -0
- data/ext/ruby_vips.c +131 -0
- data/ext/ruby_vips.h +26 -0
- data/ext/writer.c +346 -0
- data/lib/vips.rb +7 -0
- data/lib/vips/reader.rb +183 -0
- data/lib/vips/version.rb +3 -0
- data/lib/vips/writer.rb +275 -0
- data/ruby-vips.gemspec +93 -0
- metadata +163 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
VALUE img_to_mask(VALUE);
|
2
|
+
VALUE img_dup(VALUE);
|
3
|
+
VALUE img_copy_swap(VALUE);
|
4
|
+
VALUE img_copy_native(VALUE, VALUE);
|
5
|
+
VALUE img_copy_file(VALUE);
|
6
|
+
VALUE img_clip2fmt(VALUE, VALUE);
|
7
|
+
VALUE img_scale(VALUE);
|
8
|
+
VALUE img_msb(int, VALUE*, VALUE);
|
9
|
+
VALUE img_c2amph(VALUE);
|
10
|
+
VALUE img_c2rect(VALUE);
|
11
|
+
VALUE img_ri2c(VALUE, VALUE);
|
12
|
+
VALUE img_c2imag(VALUE);
|
13
|
+
VALUE img_c2real(VALUE);
|
14
|
+
VALUE img_scaleps(VALUE);
|
15
|
+
VALUE img_falsecolour(VALUE);
|
16
|
+
VALUE img_s_gaussnoise(VALUE, VALUE, VALUE, VALUE, VALUE);
|
17
|
+
VALUE img_s_black(VALUE, VALUE, VALUE, VALUE);
|
18
|
+
VALUE img_s_text(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
19
|
+
VALUE img_extract_band(int, VALUE*, VALUE);
|
20
|
+
VALUE img_extract_area(int, VALUE*, VALUE);
|
21
|
+
VALUE img_embed(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
22
|
+
VALUE img_bandjoin(int, VALUE *argv, VALUE);
|
23
|
+
VALUE img_insert_noexpand(VALUE, VALUE, VALUE, VALUE);
|
24
|
+
VALUE img_insert(int, VALUE *argv, VALUE);
|
25
|
+
VALUE img_lrjoin(VALUE, VALUE);
|
26
|
+
VALUE img_tbjoin(VALUE, VALUE);
|
27
|
+
VALUE img_replicate(VALUE, VALUE, VALUE);
|
28
|
+
VALUE img_grid(VALUE, VALUE, VALUE, VALUE);
|
29
|
+
VALUE img_wrap(VALUE, VALUE, VALUE);
|
30
|
+
VALUE img_fliphor(VALUE);
|
31
|
+
VALUE img_flipver(VALUE);
|
32
|
+
VALUE img_rot90(VALUE);
|
33
|
+
VALUE img_rot180(VALUE);
|
34
|
+
VALUE img_rot270(VALUE);
|
35
|
+
VALUE img_subsample(int, VALUE*, VALUE);
|
36
|
+
VALUE img_zoom(int, VALUE*, VALUE);
|
37
|
+
void init_Image_conversion();
|
@@ -0,0 +1,371 @@
|
|
1
|
+
#include "ruby_vips.h"
|
2
|
+
#include "image.h"
|
3
|
+
#include "mask.h"
|
4
|
+
#include "image_convolution.h"
|
5
|
+
|
6
|
+
/*
|
7
|
+
* call-seq:
|
8
|
+
* im.conv(mask) -> image
|
9
|
+
*
|
10
|
+
* Convolve *self* with <i>mask</i>. The output image always has the same band format
|
11
|
+
* as *self*. Non-complex images only.
|
12
|
+
*
|
13
|
+
* Each output pixel is calculated as sigma[i]{pixel[i] * <i>mask</i>[i]} /
|
14
|
+
* scale + offset, where scale and offset are part of <i>mask</i>. For integer
|
15
|
+
* *self*, the division by scale includes round-to-nearest.
|
16
|
+
*
|
17
|
+
* <i>mask</i> can be an array in which case scale defaults to 1 and offset
|
18
|
+
* defaults to zero. <i>mask</i> can also be a Mask object.
|
19
|
+
*/
|
20
|
+
|
21
|
+
VALUE
|
22
|
+
img_conv(VALUE obj, VALUE m)
|
23
|
+
{
|
24
|
+
DOUBLEMASK *dmask;
|
25
|
+
INTMASK *imask;
|
26
|
+
|
27
|
+
GetImg(obj, data, im);
|
28
|
+
OutImg2(obj, m, new, data_new, im_new);
|
29
|
+
|
30
|
+
mask_arg2mask(m, &imask, &dmask);
|
31
|
+
|
32
|
+
if (imask) {
|
33
|
+
if (im_conv(im, im_new, imask))
|
34
|
+
vips_lib_error();
|
35
|
+
} else if (im_conv_f(im, im_new, dmask))
|
36
|
+
vips_lib_error();
|
37
|
+
|
38
|
+
return new;
|
39
|
+
}
|
40
|
+
|
41
|
+
/*
|
42
|
+
* call-seq:
|
43
|
+
* im.convsep(mask) -> image
|
44
|
+
*
|
45
|
+
* Perform a separable convolution of *self* with <i>mask</i> using integer
|
46
|
+
* arithmetic.
|
47
|
+
*
|
48
|
+
* <i>mask</i> must be 1xn or nx1 elements.
|
49
|
+
*
|
50
|
+
* The output image always has the same band format as *self*. Non-complex
|
51
|
+
* images only.
|
52
|
+
*
|
53
|
+
* The image is convolved twice: once with <i>mask</i> and then again with
|
54
|
+
* <i>mask</i> rotated by 90 degrees. This is much faster for certain types of
|
55
|
+
* mask (gaussian blur, for example) than doing a full 2D convolution.
|
56
|
+
*
|
57
|
+
* Each output pixel is calculated as sigma[i]{pixel[i] * <i>mask</i>[i]} /
|
58
|
+
* scale + offset, where scale and offset are part of <i>mask</i>. For integer
|
59
|
+
* *self*, the division by scale includes round-to-nearest.
|
60
|
+
*
|
61
|
+
* <i>mask</i> can be an array in which case scale defaults to 1 and offset
|
62
|
+
* defaults to zero. <i>mask</i> can also be a Mask object.
|
63
|
+
*/
|
64
|
+
|
65
|
+
VALUE
|
66
|
+
img_convsep(VALUE obj, VALUE mask)
|
67
|
+
{
|
68
|
+
DOUBLEMASK *dmask;
|
69
|
+
INTMASK *imask;
|
70
|
+
|
71
|
+
GetImg(obj, data, im);
|
72
|
+
OutImg2(obj, mask, new, data_new, im_new);
|
73
|
+
|
74
|
+
mask_arg2mask(mask, &imask, &dmask);
|
75
|
+
|
76
|
+
if(imask) {
|
77
|
+
if (im_convsep(im, im_new, imask))
|
78
|
+
vips_lib_error();
|
79
|
+
} else if (im_convsep_f(im, im_new, dmask))
|
80
|
+
vips_lib_error();
|
81
|
+
|
82
|
+
return new;
|
83
|
+
}
|
84
|
+
|
85
|
+
/*
|
86
|
+
* call-seq:
|
87
|
+
* im.compass(mask) -> image
|
88
|
+
*
|
89
|
+
* *self* is convolved 8 times with <i>mask</i>, each time <i>mask</i> is
|
90
|
+
* rotated by 45 degrees. Each output pixel is the largest absolute value of
|
91
|
+
* the 8 convolutions.
|
92
|
+
*
|
93
|
+
* <i>mask</i> can be an array or a Mask object.
|
94
|
+
*/
|
95
|
+
|
96
|
+
VALUE
|
97
|
+
img_compass(VALUE obj, VALUE mask)
|
98
|
+
{
|
99
|
+
INTMASK *imask;
|
100
|
+
GetImg(obj, data, im);
|
101
|
+
OutImg2(obj, mask, new, data_new, im_new);
|
102
|
+
|
103
|
+
mask_arg2mask(mask, &imask, NULL);
|
104
|
+
|
105
|
+
if (im_compass(im, im_new, imask))
|
106
|
+
vips_lib_error();
|
107
|
+
|
108
|
+
return new;
|
109
|
+
}
|
110
|
+
|
111
|
+
/*
|
112
|
+
* call-seq:
|
113
|
+
* im.gradient(mask) -> image
|
114
|
+
*
|
115
|
+
* *self* is convolved with <i>mask</i> and with <i>mask</i> after a 90 degree
|
116
|
+
* rotation. The result is the sum of the absolute value of the two
|
117
|
+
* convolutions.
|
118
|
+
*
|
119
|
+
* <i>mask</i> can be an array or a Mask object.
|
120
|
+
*/
|
121
|
+
|
122
|
+
VALUE
|
123
|
+
img_gradient(VALUE obj, VALUE mask)
|
124
|
+
{
|
125
|
+
INTMASK *imask;
|
126
|
+
|
127
|
+
GetImg(obj, data, im);
|
128
|
+
OutImg2(obj, mask, new, data_new, im_new);
|
129
|
+
|
130
|
+
mask_arg2mask(mask, &imask, NULL);
|
131
|
+
|
132
|
+
if (im_gradient(im, im_new, imask) )
|
133
|
+
vips_lib_error();
|
134
|
+
|
135
|
+
return new;
|
136
|
+
}
|
137
|
+
|
138
|
+
/*
|
139
|
+
* call-seq:
|
140
|
+
* im.lindetect(mask) -> image
|
141
|
+
*
|
142
|
+
* *self* is convolved four times with @mask, each time @mask is rotated by 45
|
143
|
+
* degrees. Each output pixel is the largest absolute value of the four
|
144
|
+
* convolutions.
|
145
|
+
*
|
146
|
+
* <i>mask</i> can be an array or a Mask object.
|
147
|
+
*/
|
148
|
+
|
149
|
+
VALUE
|
150
|
+
img_lindetect(VALUE obj, VALUE mask)
|
151
|
+
{
|
152
|
+
INTMASK *imask;
|
153
|
+
|
154
|
+
GetImg(obj, data, im);
|
155
|
+
OutImg2(obj, mask, new, data_new, im_new);
|
156
|
+
|
157
|
+
mask_arg2mask(mask, &imask, NULL);
|
158
|
+
|
159
|
+
if (im_lindetect(im, im_new, imask))
|
160
|
+
vips_lib_error();
|
161
|
+
|
162
|
+
return new;
|
163
|
+
}
|
164
|
+
|
165
|
+
/*
|
166
|
+
* call-seq:
|
167
|
+
* im.sharpen(mask_size, x1, y2, y3, m1, m2) -> image
|
168
|
+
*
|
169
|
+
* Selectively sharpen the L channel of a LAB image. Works for :LABQ coding and
|
170
|
+
* LABS images.
|
171
|
+
*
|
172
|
+
* The operation performs a gaussian blur of size <i>mask_size</i> and
|
173
|
+
* subtract from *self* to generate a high-frequency signal. This signal is
|
174
|
+
* passed through a lookup table formed from the five parameters and added back
|
175
|
+
* to *self*.
|
176
|
+
*
|
177
|
+
*
|
178
|
+
* For printing, we recommend the following settings:
|
179
|
+
*
|
180
|
+
* mask_size == 7
|
181
|
+
* x1 == 1.5
|
182
|
+
* y2 == 20 (don't brighten by more than 20 L*)
|
183
|
+
* y3 == 50 (can darken by up to 50 L*)
|
184
|
+
*
|
185
|
+
* m1 == 1 (some sharpening in flat areas)
|
186
|
+
* m2 == 2 (more sharpening in jaggy areas)
|
187
|
+
*
|
188
|
+
* If you want more or less sharpening, we suggest you just change the
|
189
|
+
* <i>m1</i> and <i>m2</i> parameters.
|
190
|
+
*
|
191
|
+
* The <i>mask_size</i> parameter changes the width of the fringe and can be
|
192
|
+
* adjusted according to the output printing resolution. As an approximate
|
193
|
+
* guideline, use 3 for 4 pixels/mm (CRT display resolution), 5 for 8
|
194
|
+
* pixels/mm, 7 for 12 pixels/mm and 9 for 16 pixels/mm (300 dpi == 12
|
195
|
+
* pixels/mm). These figures refer to the image raster, not the half-tone
|
196
|
+
* resolution.
|
197
|
+
*/
|
198
|
+
|
199
|
+
VALUE
|
200
|
+
img_sharpen(VALUE obj, VALUE mask_size, VALUE x1, VALUE y2, VALUE y3, VALUE m1,
|
201
|
+
VALUE m2)
|
202
|
+
{
|
203
|
+
GetImg(obj, data, im);
|
204
|
+
OutImg(obj, new, data_new, im_new);
|
205
|
+
|
206
|
+
if (im_sharpen(im, im_new, NUM2INT(mask_size), NUM2DBL(x1), NUM2DBL(y2),
|
207
|
+
NUM2DBL(y3), NUM2DBL(m1), NUM2DBL(m2)))
|
208
|
+
vips_lib_error();
|
209
|
+
|
210
|
+
return new;
|
211
|
+
}
|
212
|
+
|
213
|
+
/*
|
214
|
+
* call-seq:
|
215
|
+
* im.grad_x -> image
|
216
|
+
*
|
217
|
+
* Find horizontal differences between adjacent pixels.
|
218
|
+
*
|
219
|
+
* Generates an image where the value of each pixel is the difference between
|
220
|
+
* it and the pixel to its right. The output has the same height as the input
|
221
|
+
* and one pixel less width. One-band integer formats only. The result is
|
222
|
+
* always band format :INT.
|
223
|
+
*
|
224
|
+
* This operation is much faster than (though equivalent to) Image#conv with
|
225
|
+
* the mask [[-1, 1]].
|
226
|
+
*/
|
227
|
+
|
228
|
+
VALUE
|
229
|
+
img_grad_x(VALUE obj)
|
230
|
+
{
|
231
|
+
RUBY_VIPS_UNARY(im_grad_x);
|
232
|
+
}
|
233
|
+
|
234
|
+
/*
|
235
|
+
* call-seq:
|
236
|
+
* im.grad_y -> image
|
237
|
+
*
|
238
|
+
* Find vertical differences between adjacent pixels.
|
239
|
+
*
|
240
|
+
* Generates an image where the value of each pixel is the difference between
|
241
|
+
* it and the pixel below it. The output has the same width as the input
|
242
|
+
* and one pixel less height. One-band integer formats only. The result is
|
243
|
+
* always band format :INT.
|
244
|
+
*
|
245
|
+
* This operation is much faster than (though equivalent to) Image#conv with
|
246
|
+
* the mask [[-1], [1]].
|
247
|
+
*/
|
248
|
+
|
249
|
+
VALUE
|
250
|
+
img_grad_y(VALUE obj)
|
251
|
+
{
|
252
|
+
RUBY_VIPS_UNARY(im_grad_y);
|
253
|
+
}
|
254
|
+
|
255
|
+
/*
|
256
|
+
* call-seq:
|
257
|
+
* im.fastcor(other_image) -> image
|
258
|
+
*
|
259
|
+
* Calculate a fast correlation surface.
|
260
|
+
*
|
261
|
+
* <i>other_image</i> is placed at every position in *self* and the sum of
|
262
|
+
* squares of differences calculated. One-band, 8-bit unsigned images only. The
|
263
|
+
* output image is always band format :UINT. <i>other_image</i> must be smaller
|
264
|
+
* than or equal to *self*. The output image is the same size as the input.
|
265
|
+
*/
|
266
|
+
|
267
|
+
VALUE
|
268
|
+
img_fastcor(VALUE obj, VALUE obj2)
|
269
|
+
{
|
270
|
+
RUBY_VIPS_BINARY(im_fastcor);
|
271
|
+
}
|
272
|
+
|
273
|
+
/*
|
274
|
+
* call-seq:
|
275
|
+
* im.spcor(other_image) -> image
|
276
|
+
*
|
277
|
+
* Calculate a correlation surface.
|
278
|
+
*
|
279
|
+
* <i>other_image</i> is placed at every position in *self* and the correlation
|
280
|
+
* coefficient calculated. One-band, 8 or 16-bit images only. *self* and
|
281
|
+
* <i>other_image</i> must have the same band format.. The output image is
|
282
|
+
* always band format :FLOAT. <i>other_image</i> must be smaller than or equal
|
283
|
+
* to *self*. The output image is the same size as *self*.
|
284
|
+
*
|
285
|
+
* The correlation coefficient is calculated as:
|
286
|
+
*
|
287
|
+
* sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl))
|
288
|
+
* c(k,l) = ------------------------------------------------
|
289
|
+
* sqrt(sumij (ref(i,j)-mean(ref))^2) *
|
290
|
+
* sqrt(sumij (inkl(i,j)-mean(inkl))^2)
|
291
|
+
*
|
292
|
+
* where inkl is the area of *self* centred at position (k,l).
|
293
|
+
*
|
294
|
+
* from Niblack "An Introduction to Digital Image Processing", Prentice/Hall,
|
295
|
+
* pp 138.
|
296
|
+
*/
|
297
|
+
|
298
|
+
VALUE
|
299
|
+
img_spcor(VALUE obj, VALUE obj2)
|
300
|
+
{
|
301
|
+
RUBY_VIPS_BINARY(im_spcor);
|
302
|
+
}
|
303
|
+
|
304
|
+
/*
|
305
|
+
* call-seq:
|
306
|
+
* im.gradcor(other_image) -> image
|
307
|
+
*
|
308
|
+
* Calculate a correlation surface.
|
309
|
+
*
|
310
|
+
* <i>other_image</i> is placed at every position in *self* and a correlation
|
311
|
+
* coefficient calculated. One-band, integer images only. *self* and
|
312
|
+
* <i>other_image</i> must have the same band format. The output image is
|
313
|
+
* always band format :FLOAT. <i>other_image</i> must be smaller than *self*.
|
314
|
+
* The output image is the same size as the input.
|
315
|
+
*
|
316
|
+
* The method takes the gradient images of the two images then takes the
|
317
|
+
* dot-product correlation of the two vector images. The vector expression of
|
318
|
+
* this method is my (tcv) own creation. It is equivalent to the complex-number
|
319
|
+
* method of:
|
320
|
+
*
|
321
|
+
* ARGYRIOU, V. et al. 2003. Estimation of sub-pixel motion using gradient
|
322
|
+
* cross correlation. Electronics Letters, 39 (13).
|
323
|
+
*/
|
324
|
+
|
325
|
+
VALUE
|
326
|
+
img_gradcor(VALUE obj, VALUE obj2)
|
327
|
+
{
|
328
|
+
RUBY_VIPS_BINARY(im_gradcor);
|
329
|
+
}
|
330
|
+
|
331
|
+
/*
|
332
|
+
* call-seq:
|
333
|
+
* im.contrast_surface(half_win_size, spacing) -> image
|
334
|
+
*
|
335
|
+
* Generate an image where the value of each pixel represents the contrast
|
336
|
+
* within a window of half_win_size from the corresponsing point in the input
|
337
|
+
* image. Sub-sample by a factor of spacing.
|
338
|
+
*/
|
339
|
+
|
340
|
+
VALUE
|
341
|
+
img_contrast_surface(VALUE obj, VALUE half_win_size, VALUE spacing)
|
342
|
+
{
|
343
|
+
GetImg(obj, data, im);
|
344
|
+
OutImg(obj, new, data_new, im_new);
|
345
|
+
|
346
|
+
if (im_contrast_surface(im, im_new, NUM2INT(half_win_size),
|
347
|
+
NUM2INT(spacing)))
|
348
|
+
vips_lib_error();
|
349
|
+
|
350
|
+
return new;
|
351
|
+
}
|
352
|
+
|
353
|
+
/*
|
354
|
+
* call-seq:
|
355
|
+
* im.addgnoise(sigma) -> image
|
356
|
+
*
|
357
|
+
* Add gaussian noise with mean 0 and variance sigma to *self*. The noise is
|
358
|
+
* generated by averaging 12 random numbers, see page 78, PIETGEN, 1989.
|
359
|
+
*/
|
360
|
+
|
361
|
+
VALUE
|
362
|
+
img_addgnoise(VALUE obj, VALUE sigma)
|
363
|
+
{
|
364
|
+
GetImg(obj, data, im);
|
365
|
+
OutImg(obj, new, data_new, im_new);
|
366
|
+
|
367
|
+
if (im_addgnoise(im, im_new, NUM2INT(sigma)))
|
368
|
+
vips_lib_error();
|
369
|
+
|
370
|
+
return new;
|
371
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
VALUE img_conv(VALUE, VALUE);
|
2
|
+
VALUE img_convsep(VALUE, VALUE);
|
3
|
+
VALUE img_compass(VALUE, VALUE);
|
4
|
+
VALUE img_gradient(VALUE, VALUE);
|
5
|
+
VALUE img_lindetect(VALUE, VALUE);
|
6
|
+
VALUE img_sharpen(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
7
|
+
VALUE img_grad_x(VALUE);
|
8
|
+
VALUE img_grad_y(VALUE);
|
9
|
+
VALUE img_fastcor(VALUE, VALUE);
|
10
|
+
VALUE img_spcor(VALUE, VALUE);
|
11
|
+
VALUE img_gradcor(VALUE, VALUE);
|
12
|
+
VALUE img_contrast_surface(VALUE, VALUE, VALUE);
|
13
|
+
VALUE img_addgnoise(VALUE, VALUE);
|
@@ -0,0 +1,742 @@
|
|
1
|
+
#include "ruby_vips.h"
|
2
|
+
#include "image.h"
|
3
|
+
#include "image_freq_filt.h"
|
4
|
+
|
5
|
+
/*
|
6
|
+
* call-seq:
|
7
|
+
* im.fwfft -> image
|
8
|
+
*
|
9
|
+
* Transform an image to Fourier space.
|
10
|
+
*
|
11
|
+
* VIPS uses the fftw3 or fftw2 Fourier transform libraries if possible. If
|
12
|
+
* they were not available when VIPS was built, it falls back to its own
|
13
|
+
* FFT functions which are slow and only work for square images whose sides
|
14
|
+
* are a power of two.
|
15
|
+
*/
|
16
|
+
|
17
|
+
VALUE
|
18
|
+
img_fwfft(VALUE obj)
|
19
|
+
{
|
20
|
+
RUBY_VIPS_UNARY(im_fwfft);
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* call-seq:
|
25
|
+
* im.invfft -> image
|
26
|
+
*
|
27
|
+
* Transform an image from Fourier space to real space. The result is complex.
|
28
|
+
* If you are OK with a real result, use Image#invfftr instead, it's quicker.
|
29
|
+
*
|
30
|
+
* VIPS uses the fftw3 or fftw2 Fourier transform libraries if possible. If
|
31
|
+
* they were not available when VIPS was built, it falls back to its own FFT
|
32
|
+
* functions which are slow and only work for square images whose sides are a
|
33
|
+
* power of two.
|
34
|
+
*/
|
35
|
+
|
36
|
+
VALUE
|
37
|
+
img_invfft(VALUE obj)
|
38
|
+
{
|
39
|
+
RUBY_VIPS_UNARY(im_invfft);
|
40
|
+
}
|
41
|
+
|
42
|
+
/*
|
43
|
+
* call-seq:
|
44
|
+
* im.rotquad -> image
|
45
|
+
*
|
46
|
+
* Rotate the quadrants of the image so that the point that was at the
|
47
|
+
* top-left is now in the centre. Handy for moving Fourier images to optical
|
48
|
+
* space.
|
49
|
+
*/
|
50
|
+
|
51
|
+
VALUE
|
52
|
+
img_rotquad(VALUE obj)
|
53
|
+
{
|
54
|
+
RUBY_VIPS_UNARY(im_rotquad);
|
55
|
+
}
|
56
|
+
|
57
|
+
/*
|
58
|
+
* call-seq:
|
59
|
+
* im.invfftr -> image
|
60
|
+
*
|
61
|
+
* Transform an image from Fourier space to real space, giving a real result.
|
62
|
+
* This is faster than Image#invfft, which gives a complex result.
|
63
|
+
*
|
64
|
+
* VIPS uses the fftw3 or fftw2 Fourier transform libraries if possible. If
|
65
|
+
* they were not available when VIPS was built, it falls back to it's own
|
66
|
+
* FFT functions which are slow and only work for square images whose sides
|
67
|
+
* are a power of two.
|
68
|
+
*/
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
img_invfftr(VALUE obj)
|
72
|
+
{
|
73
|
+
RUBY_VIPS_UNARY(im_invfftr);
|
74
|
+
}
|
75
|
+
|
76
|
+
#if IM_MAJOR_VERSION > 7 || IM_MINOR_VERSION >= 22
|
77
|
+
|
78
|
+
/*
|
79
|
+
* call-seq:
|
80
|
+
* Image.fmask_ideal_lowpass(x, y, frequency_cutoff) -> image
|
81
|
+
*
|
82
|
+
* This operation creates a one-band float image of the size <i>x</i> by
|
83
|
+
* <i>y</i>. The image must be square, and the sides must be a power of two.
|
84
|
+
* The image has values in the range [0, 1] and is typically used for
|
85
|
+
* multiplying against frequency domain images to filter them.
|
86
|
+
*
|
87
|
+
* All masks are created with the DC component at (0, 0), so you might want to
|
88
|
+
* rotate the quadrants with im_rotquad() before viewing. The DC pixel always
|
89
|
+
* has the value 1.0.
|
90
|
+
*
|
91
|
+
* Unless noted below, all parameters are expressed as percentages, scaled to
|
92
|
+
* [0, 1].
|
93
|
+
*
|
94
|
+
* * High-pass, low-pass masks: A high pass filter mask filters the low
|
95
|
+
* frequencies while allowing the high frequencies to get through.
|
96
|
+
* The reverse happens with a low pass filter mask.
|
97
|
+
*
|
98
|
+
* * Ring-pass, ring-reject masks: A ring filter passes or rejects a range of
|
99
|
+
* frequencies. The range is specified by the <i>frequency_cutoff</i> and
|
100
|
+
* the <i>width</i>.
|
101
|
+
*
|
102
|
+
* * Band-pass, band-reject masks: These masks are used to pass or remove
|
103
|
+
* spatial frequencies around a given frequency. The position of the
|
104
|
+
* frequency to pass or remove is given by <i>frequency_cutoffx</i> and
|
105
|
+
* <i>frequency_cutoffy</i>. The size of the region around the point is
|
106
|
+
* given by <i>radius</i>.
|
107
|
+
*
|
108
|
+
* * Ideal filters: These filters pass or reject frequencies with a sharp
|
109
|
+
* cutoff at the transition.
|
110
|
+
*
|
111
|
+
* * Butterworth filters: These filters use a Butterworth function to separate
|
112
|
+
* the frequencies (see Gonzalez and Wintz, Digital Image Processing, 1987).
|
113
|
+
* The shape of the curve is controlled by <i>order</i>: higher values give
|
114
|
+
* a sharper transition.
|
115
|
+
*
|
116
|
+
* * Gaussian filters: These filters have a smooth Gaussian shape,
|
117
|
+
* controlled by <i>amplitude_cutoff</i>.
|
118
|
+
*/
|
119
|
+
|
120
|
+
VALUE
|
121
|
+
img_s_fmask_ideal_highpass(VALUE obj, VALUE x, VALUE y, VALUE frequency_cutoff)
|
122
|
+
{
|
123
|
+
OutPartial(new, data, im);
|
124
|
+
|
125
|
+
if (im_create_fmask(im, NUM2INT(x), NUM2INT(y), VIPS_MASK_IDEAL_HIGHPASS,
|
126
|
+
NUM2DBL(frequency_cutoff)))
|
127
|
+
vips_lib_error();
|
128
|
+
|
129
|
+
return new;
|
130
|
+
}
|
131
|
+
|
132
|
+
/*
|
133
|
+
* call-seq:
|
134
|
+
* Image.fmask_ideal_lowpass(x, y, frequency_cutoff) -> image
|
135
|
+
*
|
136
|
+
* See Image.fmask_ideal_highpass
|
137
|
+
*
|
138
|
+
*/
|
139
|
+
|
140
|
+
VALUE
|
141
|
+
img_s_fmask_ideal_lowpass(VALUE obj, VALUE x, VALUE y, VALUE frequency_cutoff)
|
142
|
+
{
|
143
|
+
OutPartial(new, data, im);
|
144
|
+
|
145
|
+
if (im_create_fmask(im, NUM2INT(x), NUM2INT(y),
|
146
|
+
VIPS_MASK_IDEAL_LOWPASS, NUM2DBL(frequency_cutoff)))
|
147
|
+
vips_lib_error();
|
148
|
+
|
149
|
+
return new;
|
150
|
+
}
|
151
|
+
|
152
|
+
/*
|
153
|
+
* call-seq:
|
154
|
+
* Image.fmask_butterworth_highpass(x, y, order, frequency_cutoff,
|
155
|
+
* amplitude_cutoff) -> image
|
156
|
+
*
|
157
|
+
* See Image.fmask_ideal_highpass
|
158
|
+
*/
|
159
|
+
|
160
|
+
VALUE
|
161
|
+
img_s_fmask_butterworth_highpass(VALUE obj, VALUE x, VALUE y,
|
162
|
+
VALUE order, VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
163
|
+
{
|
164
|
+
OutPartial(new, data, im);
|
165
|
+
|
166
|
+
if (im_create_fmask(im,
|
167
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_BUTTERWORTH_HIGHPASS, NUM2DBL(order),
|
168
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(amplitude_cutoff)))
|
169
|
+
vips_lib_error();
|
170
|
+
|
171
|
+
return new;
|
172
|
+
}
|
173
|
+
|
174
|
+
/*
|
175
|
+
* call-seq:
|
176
|
+
* Image.fmask_butterworth_lowpass(x, y, order, frequency_cutoff,
|
177
|
+
* amplitude_cutoff)
|
178
|
+
*
|
179
|
+
* See Image.fmask_ideal_highpass
|
180
|
+
*/
|
181
|
+
|
182
|
+
VALUE
|
183
|
+
img_s_fmask_butterworth_lowpass(VALUE obj, VALUE x, VALUE y,
|
184
|
+
VALUE order, VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
185
|
+
{
|
186
|
+
OutPartial(new, data, im);
|
187
|
+
|
188
|
+
if (im_create_fmask(im,
|
189
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_BUTTERWORTH_LOWPASS, NUM2DBL(order),
|
190
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(amplitude_cutoff)))
|
191
|
+
vips_lib_error();
|
192
|
+
|
193
|
+
return new;
|
194
|
+
}
|
195
|
+
|
196
|
+
/*
|
197
|
+
* call-seq:
|
198
|
+
* Image.fmask_gauss_highpass(x, y, frequency_cutoff, amplitude_cutoff) ->
|
199
|
+
* image
|
200
|
+
*
|
201
|
+
* See Image.fmask_ideal_highpass
|
202
|
+
*/
|
203
|
+
|
204
|
+
VALUE
|
205
|
+
img_s_fmask_gauss_highpass(VALUE obj, VALUE x, VALUE y,
|
206
|
+
VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
207
|
+
{
|
208
|
+
OutPartial(new, data, im);
|
209
|
+
|
210
|
+
if (im_create_fmask(im,
|
211
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_GAUSS_HIGHPASS,
|
212
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(amplitude_cutoff)))
|
213
|
+
vips_lib_error();
|
214
|
+
|
215
|
+
return new;
|
216
|
+
}
|
217
|
+
|
218
|
+
/*
|
219
|
+
* call-seq:
|
220
|
+
* Image.fmask_gauss_lowpass(x, y, frequency_cutoff, amplitude_cutoff) ->
|
221
|
+
* image
|
222
|
+
*
|
223
|
+
* See Image.fmask_ideal_highpass
|
224
|
+
*/
|
225
|
+
|
226
|
+
VALUE
|
227
|
+
img_s_fmask_gauss_lowpass(VALUE obj, VALUE x, VALUE y,
|
228
|
+
VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
229
|
+
{
|
230
|
+
OutPartial(new, data, im);
|
231
|
+
|
232
|
+
if (im_create_fmask(im,
|
233
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_GAUSS_LOWPASS,
|
234
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(amplitude_cutoff)))
|
235
|
+
vips_lib_error();
|
236
|
+
|
237
|
+
return new;
|
238
|
+
}
|
239
|
+
|
240
|
+
/*
|
241
|
+
* call-seq:
|
242
|
+
* Image.fmask_ideal_ringpass(x, y, frequency_cutoff, width) -> image
|
243
|
+
*
|
244
|
+
* See Image.fmask_ideal_highpass
|
245
|
+
*/
|
246
|
+
|
247
|
+
VALUE
|
248
|
+
img_s_fmask_ideal_ringpass(VALUE obj, VALUE x, VALUE y,
|
249
|
+
VALUE frequency_cutoff, VALUE width)
|
250
|
+
{
|
251
|
+
OutPartial(new, data, im);
|
252
|
+
|
253
|
+
if (im_create_fmask(im,
|
254
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_IDEAL_RINGPASS,
|
255
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(width)))
|
256
|
+
vips_lib_error();
|
257
|
+
|
258
|
+
return new;
|
259
|
+
}
|
260
|
+
|
261
|
+
/*
|
262
|
+
* call-seq:
|
263
|
+
* Image.fmask_ideal_ringreject(x, y, frequency_cutoff, width) -> image
|
264
|
+
*
|
265
|
+
* See Image.fmask_ideal_highpass
|
266
|
+
*/
|
267
|
+
|
268
|
+
VALUE
|
269
|
+
img_s_fmask_ideal_ringreject(VALUE obj, VALUE x, VALUE y,
|
270
|
+
VALUE frequency_cutoff, VALUE width)
|
271
|
+
{
|
272
|
+
OutPartial(new, data, im);
|
273
|
+
|
274
|
+
if (im_create_fmask(im,
|
275
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_IDEAL_RINGREJECT,
|
276
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(width)))
|
277
|
+
vips_lib_error();
|
278
|
+
|
279
|
+
return new;
|
280
|
+
}
|
281
|
+
|
282
|
+
/*
|
283
|
+
* call-seq:
|
284
|
+
* Image.fmask_butterworth_ringpass(x, y, order, frequency_cutoff,
|
285
|
+
* width, amplitude_cutoff) -> image
|
286
|
+
*
|
287
|
+
* See Image.fmask_ideal_highpass
|
288
|
+
*/
|
289
|
+
|
290
|
+
VALUE
|
291
|
+
img_s_fmask_butterworth_ringpass(VALUE obj, VALUE x, VALUE y,
|
292
|
+
VALUE order, VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
293
|
+
{
|
294
|
+
OutPartial(new, data, im);
|
295
|
+
|
296
|
+
if (im_create_fmask(im,
|
297
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_BUTTERWORTH_RINGPASS,
|
298
|
+
NUM2DBL(order), NUM2DBL(frequency_cutoff), NUM2DBL(width),
|
299
|
+
NUM2DBL(amplitude_cutoff)))
|
300
|
+
vips_lib_error();
|
301
|
+
|
302
|
+
return new;
|
303
|
+
}
|
304
|
+
|
305
|
+
/*
|
306
|
+
* call-seq:
|
307
|
+
* Image.fmask_butterworth_ringreject(x, y, order, frequency_cutoff,
|
308
|
+
* width, amplitude_cutoff) -> image
|
309
|
+
*
|
310
|
+
* See Image.fmask_ideal_highpass
|
311
|
+
*/
|
312
|
+
|
313
|
+
VALUE
|
314
|
+
img_s_fmask_butterworth_ringreject(VALUE obj, VALUE x, VALUE y,
|
315
|
+
VALUE order, VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
316
|
+
{
|
317
|
+
OutPartial(new, data, im);
|
318
|
+
|
319
|
+
if (im_create_fmask(im,
|
320
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_BUTTERWORTH_RINGREJECT,
|
321
|
+
NUM2DBL(order), NUM2DBL(frequency_cutoff), NUM2DBL(width),
|
322
|
+
NUM2DBL(amplitude_cutoff)))
|
323
|
+
vips_lib_error();
|
324
|
+
|
325
|
+
return new;
|
326
|
+
}
|
327
|
+
|
328
|
+
/*
|
329
|
+
* call-seq:
|
330
|
+
* Image.fmask_gauss_ringpass(x, y, frequency_cutoff, width,
|
331
|
+
* amplitude_cutoff) -> image
|
332
|
+
*
|
333
|
+
* See Image.fmask_ideal_highpass
|
334
|
+
*/
|
335
|
+
|
336
|
+
VALUE
|
337
|
+
img_s_fmask_gauss_ringpass(VALUE obj, VALUE x, VALUE y,
|
338
|
+
VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
339
|
+
{
|
340
|
+
OutPartial(new, data, im);
|
341
|
+
|
342
|
+
if (im_create_fmask(im,
|
343
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_GAUSS_RINGPASS,
|
344
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(width), NUM2DBL(amplitude_cutoff)))
|
345
|
+
vips_lib_error();
|
346
|
+
|
347
|
+
return new;
|
348
|
+
}
|
349
|
+
|
350
|
+
/*
|
351
|
+
* call-seq:
|
352
|
+
* Image.fmask_gauss_ringreject(x, y, frequency_cutoff, width,
|
353
|
+
* amplitude_cutoff) -> image
|
354
|
+
*
|
355
|
+
* See Image.fmask_ideal_highpass
|
356
|
+
*/
|
357
|
+
|
358
|
+
VALUE
|
359
|
+
img_s_fmask_gauss_ringreject(VALUE obj, VALUE x, VALUE y,
|
360
|
+
VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
361
|
+
{
|
362
|
+
OutPartial(new, data, im);
|
363
|
+
|
364
|
+
if (im_create_fmask(im,
|
365
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_GAUSS_RINGREJECT,
|
366
|
+
NUM2DBL(frequency_cutoff), NUM2DBL(width), NUM2DBL(amplitude_cutoff)))
|
367
|
+
vips_lib_error();
|
368
|
+
|
369
|
+
return new;
|
370
|
+
}
|
371
|
+
|
372
|
+
/*
|
373
|
+
* call-seq:
|
374
|
+
* Image.fmask_ideal_bandpass(x, y, frequency_cutoffx, frequency_cutoffy,
|
375
|
+
* radius) -> image
|
376
|
+
*
|
377
|
+
* See Image.fmask_ideal_highpass
|
378
|
+
*/
|
379
|
+
|
380
|
+
VALUE
|
381
|
+
img_s_fmask_ideal_bandpass(VALUE obj, VALUE x, VALUE y,
|
382
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius)
|
383
|
+
{
|
384
|
+
OutPartial(new, data, im);
|
385
|
+
|
386
|
+
if (im_create_fmask(im,
|
387
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_IDEAL_BANDPASS,
|
388
|
+
NUM2DBL(frequency_cutoffx), NUM2DBL(frequency_cutoffy),
|
389
|
+
NUM2DBL(radius)))
|
390
|
+
vips_lib_error();
|
391
|
+
|
392
|
+
return new;
|
393
|
+
}
|
394
|
+
|
395
|
+
/*
|
396
|
+
* call-seq:
|
397
|
+
* Image.fmask_ideal_bandreject(x, y, frequency_cutoffx, frequency_cutoffy,
|
398
|
+
* radius)
|
399
|
+
*
|
400
|
+
* See Image.fmask_ideal_highpass
|
401
|
+
*/
|
402
|
+
|
403
|
+
VALUE
|
404
|
+
img_s_fmask_ideal_bandreject(VALUE obj, VALUE x, VALUE y,
|
405
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius)
|
406
|
+
{
|
407
|
+
OutPartial(new, data, im);
|
408
|
+
|
409
|
+
if (im_create_fmask(im,
|
410
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_IDEAL_BANDREJECT,
|
411
|
+
NUM2DBL(frequency_cutoffx), NUM2DBL(frequency_cutoffy),
|
412
|
+
NUM2DBL(radius)))
|
413
|
+
vips_lib_error();
|
414
|
+
|
415
|
+
return new;
|
416
|
+
}
|
417
|
+
|
418
|
+
/*
|
419
|
+
* call-seq:
|
420
|
+
* Image.fmask_butterworth_bandpass(x, y, order, frequency_cutoffx,
|
421
|
+
* frequency_cutoffy, radius, amplitude_cutoff) -> image
|
422
|
+
*
|
423
|
+
* See Image.fmask_ideal_highpass
|
424
|
+
*/
|
425
|
+
|
426
|
+
VALUE
|
427
|
+
img_s_fmask_butterworth_bandpass(VALUE obj, VALUE x, VALUE y,
|
428
|
+
VALUE order, VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
429
|
+
VALUE amplitude_cutoff)
|
430
|
+
{
|
431
|
+
OutPartial(new, data, im);
|
432
|
+
|
433
|
+
if (im_create_fmask(im,
|
434
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_BUTTERWORTH_BANDPASS,
|
435
|
+
NUM2DBL(order), NUM2DBL(frequency_cutoffx), NUM2DBL(frequency_cutoffy),
|
436
|
+
NUM2DBL(radius), NUM2DBL(amplitude_cutoff)))
|
437
|
+
vips_lib_error();
|
438
|
+
|
439
|
+
return new;
|
440
|
+
}
|
441
|
+
|
442
|
+
/*
|
443
|
+
* call-seq:
|
444
|
+
* Image.fmask_butterworth_bandreject(x, y, order, frequency_cutoffx,
|
445
|
+
* frequency_cutoffy, radius, amplitude_cutoff) -> image
|
446
|
+
*
|
447
|
+
* See Image.fmask_ideal_highpass
|
448
|
+
*/
|
449
|
+
|
450
|
+
VALUE
|
451
|
+
img_s_fmask_butterworth_bandreject(VALUE obj, VALUE x, VALUE y,
|
452
|
+
VALUE order, VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
453
|
+
VALUE amplitude_cutoff)
|
454
|
+
{
|
455
|
+
OutPartial(new, data, im);
|
456
|
+
|
457
|
+
if (im_create_fmask(im,
|
458
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_BUTTERWORTH_BANDREJECT,
|
459
|
+
NUM2DBL(order), NUM2DBL(frequency_cutoffx), NUM2DBL(frequency_cutoffy),
|
460
|
+
NUM2DBL(radius), NUM2DBL(amplitude_cutoff)))
|
461
|
+
vips_lib_error();
|
462
|
+
|
463
|
+
return new;
|
464
|
+
}
|
465
|
+
|
466
|
+
/*
|
467
|
+
* call-seq:
|
468
|
+
* Image.fmask_gaus_bandpass(x, y, frequency_cutoffx, frequency_cutoffy,
|
469
|
+
* radius, amplitude_cutoff) -> image
|
470
|
+
*
|
471
|
+
* See Image.fmask_ideal_highpass
|
472
|
+
*/
|
473
|
+
|
474
|
+
VALUE
|
475
|
+
img_s_fmask_gauss_bandpass(VALUE obj, VALUE x, VALUE y,
|
476
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
477
|
+
VALUE amplitude_cutoff)
|
478
|
+
{
|
479
|
+
OutPartial(new, data, im);
|
480
|
+
|
481
|
+
if (im_create_fmask(im,
|
482
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_GAUSS_BANDPASS,
|
483
|
+
NUM2DBL(frequency_cutoffx), NUM2DBL(frequency_cutoffy), NUM2DBL(radius),
|
484
|
+
NUM2DBL(amplitude_cutoff)))
|
485
|
+
vips_lib_error();
|
486
|
+
|
487
|
+
return new;
|
488
|
+
}
|
489
|
+
|
490
|
+
/*
|
491
|
+
* call-seq:
|
492
|
+
* Image.fmask_gauss_bandreject, x, y, frequency_cutoffx, frequency_cutoffy,
|
493
|
+
* radius, amplitude_cutoff) -> image
|
494
|
+
*
|
495
|
+
* See Image.fmask_ideal_highpass
|
496
|
+
*/
|
497
|
+
|
498
|
+
VALUE
|
499
|
+
img_s_fmask_gauss_bandreject(VALUE obj, VALUE x, VALUE y,
|
500
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
501
|
+
VALUE amplitude_cutoff)
|
502
|
+
{
|
503
|
+
OutPartial(new, data, im);
|
504
|
+
|
505
|
+
if (im_create_fmask(im,
|
506
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_GAUSS_BANDREJECT,
|
507
|
+
NUM2DBL(frequency_cutoffx), NUM2DBL(frequency_cutoffy), NUM2DBL(radius),
|
508
|
+
NUM2DBL(amplitude_cutoff)))
|
509
|
+
vips_lib_error();
|
510
|
+
|
511
|
+
return new;
|
512
|
+
}
|
513
|
+
|
514
|
+
/*
|
515
|
+
* call-seq:
|
516
|
+
* Image.fmask_fractal_flt(x, y, fractal_dimension) -> image
|
517
|
+
*
|
518
|
+
* This mask is handy for filtering images of gaussian noise in order to create
|
519
|
+
* surfaces of a given fractal dimension. @fractal_dimension should be between
|
520
|
+
* 2 and 3.
|
521
|
+
*/
|
522
|
+
|
523
|
+
VALUE
|
524
|
+
img_s_fmask_fractal_flt(VALUE obj, VALUE x, VALUE y,
|
525
|
+
VALUE fractal_dimension)
|
526
|
+
{
|
527
|
+
OutPartial(new, data, im);
|
528
|
+
|
529
|
+
if (im_create_fmask(im,
|
530
|
+
NUM2INT(x), NUM2INT(y), VIPS_MASK_FRACTAL_FLT,
|
531
|
+
NUM2DBL(fractal_dimension)))
|
532
|
+
vips_lib_error();
|
533
|
+
|
534
|
+
return new;
|
535
|
+
}
|
536
|
+
|
537
|
+
#else
|
538
|
+
|
539
|
+
VALUE
|
540
|
+
img_s_fmask_ideal_highpass(VALUE obj, VALUE x, VALUE y,
|
541
|
+
VALUE frequency_cutoff)
|
542
|
+
{
|
543
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
544
|
+
}
|
545
|
+
|
546
|
+
VALUE
|
547
|
+
img_s_fmask_ideal_lowpass(VALUE obj, VALUE x, VALUE y,
|
548
|
+
VALUE frequency_cutoff)
|
549
|
+
{
|
550
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
551
|
+
}
|
552
|
+
|
553
|
+
VALUE
|
554
|
+
img_s_fmask_butterworth_highpass(VALUE obj, VALUE x, VALUE y,
|
555
|
+
VALUE order, VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
556
|
+
{
|
557
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
558
|
+
}
|
559
|
+
|
560
|
+
VALUE
|
561
|
+
img_s_fmask_butterworth_lowpass(VALUE obj, VALUE x, VALUE y,
|
562
|
+
VALUE order, VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
563
|
+
{
|
564
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
565
|
+
}
|
566
|
+
|
567
|
+
VALUE
|
568
|
+
img_s_fmask_gauss_highpass(VALUE obj, VALUE x, VALUE y,
|
569
|
+
VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
570
|
+
{
|
571
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
572
|
+
}
|
573
|
+
|
574
|
+
VALUE
|
575
|
+
img_s_fmask_gauss_lowpass(VALUE obj, VALUE x, VALUE y,
|
576
|
+
VALUE frequency_cutoff, VALUE amplitude_cutoff)
|
577
|
+
{
|
578
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
579
|
+
}
|
580
|
+
|
581
|
+
VALUE
|
582
|
+
img_s_fmask_ideal_ringpass(VALUE obj, VALUE x, VALUE y,
|
583
|
+
VALUE frequency_cutoff, VALUE width)
|
584
|
+
{
|
585
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
586
|
+
}
|
587
|
+
|
588
|
+
VALUE
|
589
|
+
img_s_fmask_ideal_ringreject(VALUE obj, VALUE x, VALUE y,
|
590
|
+
VALUE frequency_cutoff, VALUE width)
|
591
|
+
{
|
592
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
593
|
+
}
|
594
|
+
|
595
|
+
VALUE
|
596
|
+
img_s_fmask_butterworth_ringpass(VALUE obj, VALUE x, VALUE y,
|
597
|
+
VALUE order, VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
598
|
+
{
|
599
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
600
|
+
}
|
601
|
+
|
602
|
+
VALUE
|
603
|
+
img_s_fmask_butterworth_ringreject(VALUE obj, VALUE x, VALUE y,
|
604
|
+
VALUE order, VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
605
|
+
{
|
606
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
607
|
+
}
|
608
|
+
|
609
|
+
VALUE
|
610
|
+
img_s_fmask_gauss_ringpass(VALUE obj, VALUE x, VALUE y,
|
611
|
+
VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
612
|
+
{
|
613
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
614
|
+
}
|
615
|
+
|
616
|
+
VALUE
|
617
|
+
img_s_fmask_gauss_ringreject(VALUE obj, VALUE x, VALUE y,
|
618
|
+
VALUE frequency_cutoff, VALUE width, VALUE amplitude_cutoff)
|
619
|
+
{
|
620
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
621
|
+
}
|
622
|
+
|
623
|
+
VALUE
|
624
|
+
img_s_fmask_ideal_bandpass(VALUE obj, VALUE x, VALUE y,
|
625
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius)
|
626
|
+
{
|
627
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
628
|
+
}
|
629
|
+
|
630
|
+
VALUE
|
631
|
+
img_s_fmask_ideal_bandreject(VALUE obj, VALUE x, VALUE y,
|
632
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius)
|
633
|
+
{
|
634
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
635
|
+
}
|
636
|
+
|
637
|
+
VALUE
|
638
|
+
img_s_fmask_butterworth_bandpass(VALUE obj, VALUE x, VALUE y,
|
639
|
+
VALUE order, VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
640
|
+
VALUE amplitude_cutoff)
|
641
|
+
{
|
642
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
643
|
+
}
|
644
|
+
|
645
|
+
VALUE
|
646
|
+
img_s_fmask_butterworth_bandreject(VALUE obj, VALUE x, VALUE y,
|
647
|
+
VALUE order, VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
648
|
+
VALUE amplitude_cutoff)
|
649
|
+
{
|
650
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
651
|
+
}
|
652
|
+
|
653
|
+
VALUE
|
654
|
+
img_s_fmask_gauss_bandpass(VALUE obj, VALUE x, VALUE y,
|
655
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
656
|
+
VALUE amplitude_cutoff)
|
657
|
+
{
|
658
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
659
|
+
}
|
660
|
+
|
661
|
+
VALUE
|
662
|
+
img_s_fmask_gauss_bandreject(VALUE obj, VALUE x, VALUE y,
|
663
|
+
VALUE frequency_cutoffx, VALUE frequency_cutoffy, VALUE radius,
|
664
|
+
VALUE amplitude_cutoff)
|
665
|
+
{
|
666
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
667
|
+
}
|
668
|
+
|
669
|
+
VALUE
|
670
|
+
img_s_fmask_fractal_flt(VALUE obj, VALUE x, VALUE y,
|
671
|
+
VALUE fractal_dimension)
|
672
|
+
{
|
673
|
+
rb_raise(eVIPSError, "Operation not supported with your version of VIPS.");
|
674
|
+
}
|
675
|
+
|
676
|
+
#endif
|
677
|
+
|
678
|
+
/*
|
679
|
+
* call-seq:
|
680
|
+
* im.freqflt(other_image) -> image
|
681
|
+
*
|
682
|
+
* Filter an image in Fourier space.
|
683
|
+
*
|
684
|
+
* *self* is transformed to Fourier space, multipled with <i>other_image</i>,
|
685
|
+
* then transformed back to real space. If *self* is already a complex image,
|
686
|
+
* just multiply then inverse transform.
|
687
|
+
*/
|
688
|
+
|
689
|
+
VALUE
|
690
|
+
img_freqflt(VALUE obj, VALUE obj2)
|
691
|
+
{
|
692
|
+
RUBY_VIPS_BINARY(im_freqflt);
|
693
|
+
}
|
694
|
+
|
695
|
+
/*
|
696
|
+
* call-seq:
|
697
|
+
* im.disp_ps -> image
|
698
|
+
*
|
699
|
+
* Make a displayable (ie. 8-bit unsigned int) power spectrum.
|
700
|
+
*
|
701
|
+
* If *self* is non-complex, it is transformed to Fourier space. Then the
|
702
|
+
* absolute value is passed through Image#scaleps, and Image#rotquad.
|
703
|
+
*/
|
704
|
+
|
705
|
+
VALUE
|
706
|
+
img_disp_ps(VALUE obj)
|
707
|
+
{
|
708
|
+
RUBY_VIPS_UNARY(im_disp_ps);
|
709
|
+
}
|
710
|
+
|
711
|
+
/*
|
712
|
+
* call-seq:
|
713
|
+
* im.phasecor_fft(other_image) -> image
|
714
|
+
*
|
715
|
+
* Convert the two input images to Fourier space, calculate phase-correlation,
|
716
|
+
* back to real space.
|
717
|
+
*/
|
718
|
+
|
719
|
+
VALUE
|
720
|
+
img_phasecor_fft(VALUE obj, VALUE obj2)
|
721
|
+
{
|
722
|
+
RUBY_VIPS_BINARY(im_phasecor_fft);
|
723
|
+
}
|
724
|
+
|
725
|
+
/*
|
726
|
+
* call-seq:
|
727
|
+
* Image.fractsurf(size, frd) -> image
|
728
|
+
*
|
729
|
+
* Generate an image of size <i>size</i> and fractal dimension <i>frd</i>. The
|
730
|
+
* dimension should be between 2 and 3.
|
731
|
+
*/
|
732
|
+
|
733
|
+
VALUE
|
734
|
+
img_s_fractsurf(VALUE obj, VALUE size, VALUE frd)
|
735
|
+
{
|
736
|
+
OutPartial(new, data, im);
|
737
|
+
|
738
|
+
if (im_fractsurf(im, NUM2INT(size), NUM2DBL(frd)))
|
739
|
+
vips_lib_error();
|
740
|
+
|
741
|
+
return new;
|
742
|
+
}
|