~ubuntu-branches/ubuntu/vivid/nip2/vivid-proposed

« back to all changes in this revision

Viewing changes to share/nip2/compat/7.14/Tasks.def

  • Committer: Bazaar Package Importer
  • Author(s): Michael Terry
  • Date: 2009-05-12 09:26:46 UTC
  • mfrom: (1.2.11 upstream) (2.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090512092646-j8lb1w2x69pvgma4
Tags: 7.18.1-1ubuntu1
* Merge from debian unstable (LP: #375435), remaining changes:
  - debian/control: Also Recommend abrowser

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Tasks_capture_item = class
 
2
        Menupullright "_Capture" 
 
3
                "useful stuff for capturing and preprocessing images" {
 
4
 
 
5
        Csv_import_item = class
 
6
                Menuaction "_CSV Import" "read a file of comma-separated values" {
 
7
                action = class 
 
8
                        _result {
 
9
                        _vislevel = 3;
 
10
 
 
11
                        path = Pathname "File to load" "empty";
 
12
                        start_line = Expression "Start at line" 1;
 
13
                        rows = Expression "Lines to read (-1 for whole file)" (-1);
 
14
                        whitespace = String "Whitespace characters" " \"";
 
15
                        separator = String "Separator characters" ",;\t";
 
16
 
 
17
                        _result
 
18
                                = Image blank, path.value == "empty"
 
19
                                = Image (im_csv2vips filename)
 
20
                        {
 
21
                                filename = search (expand path.value) ++ ":" ++
 
22
                                        "skip:" ++ print (start_line.expr - 1) ++ "," ++
 
23
                                        "whi:" ++ escape whitespace.value ++ "," ++
 
24
                                        "sep:" ++ escape separator.value ++ "," ++
 
25
                                        "line:" ++ print rows.expr;
 
26
 
 
27
                                // prefix any ',' with a '\' in the separators line
 
28
                                escape x 
 
29
                                        = foldr prefix [] x
 
30
                                {
 
31
                                        prefix x l
 
32
                                                = '\\' : x : l, x == ','
 
33
                                                = x : l;
 
34
                                }
 
35
 
 
36
                                blank = image_new 1 1 1 
 
37
                                        Image_format.DOUBLE Image_coding.NOCODING Image_type.B_W 
 
38
                                        0 0 0;
 
39
                        }
 
40
                }
 
41
        }
 
42
 
 
43
        // interpret Analyze header for layout and calibration
 
44
        Analyze7_header_item = class
 
45
                Menuaction "_Interpret Analyze 7 Header" 
 
46
                        "examine the Analyze header and set layout and value" {
 
47
                action x 
 
48
                        = x'''
 
49
                {
 
50
                        // read bits of header
 
51
                        dim n = get_header ("dsr-image_dimension.dim[" ++ print n ++ "]");
 
52
                        dim0 = dim 0 x;
 
53
                        dim1 = dim 1 x;
 
54
                        dim2 = dim 2 x;
 
55
                        dim3 = dim 3 x;
 
56
                        dim4 = dim 4 x;
 
57
                        dim5 = dim 5 x;
 
58
                        dim6 = dim 6 x;
 
59
                        dim7 = dim 7 x;
 
60
                        glmax = get_header "dsr-image_dimension.glmax" x;
 
61
                        cal_max = get_header "dsr-image_dimension.cal_max" x;
 
62
        
 
63
                        // oops, now a nop
 
64
                        x' = x;
 
65
        
 
66
                        // lay out higher dimensions width-ways
 
67
                        x'' 
 
68
                                = grid dim2 dim3 1 x', dim0 == 3
 
69
                                = grid dim2 dim3 dim4 x', dim0 == 4
 
70
                                = grid (dim2 * dim4) dim5 1 (grid dim2 dim3 dim4) x', dim0 == 5
 
71
                                = grid (dim2 * dim4) dim5 dim6 (grid dim2 dim3 dim4) x', dim0 == 6
 
72
                                = grid (dim2 * dim4 * dim6) dim7 1 
 
73
                                        (grid (dim2 * dim4) dim5 dim6 (grid dim2 dim3 dim4)) x', 
 
74
                                                dim0 == 7
 
75
                                = error (_ "unsupported dimension " ++ dim0);
 
76
        
 
77
                        // multiply by scale factor to get kBeq
 
78
                        x''' = x'' * (cal_max / glmax);
 
79
                }
 
80
        }
 
81
 
 
82
        Video_item = class 
 
83
                Menuaction "Capture _Video Frame" "capture a frame of still video" {
 
84
                // shortcut to prefs
 
85
                prefs = Workspaces.Preferences;
 
86
 
 
87
                action = class
 
88
                        _result {
 
89
                        _vislevel = 3;
 
90
 
 
91
                        device = prefs.VIDEO_DEVICE;
 
92
                        channel = Option "Input channel" [
 
93
                                "TV",
 
94
                                "Composite 1",
 
95
                                "Composite 2",
 
96
                                "Composite 3"
 
97
                        ] prefs.VIDEO_CHANNEL;
 
98
                        b = Scale "Brightness" 0 32767 prefs.VIDEO_BRIGHTNESS;
 
99
                        col = Scale "Colour" 0 32767 prefs.VIDEO_COLOUR;
 
100
                        con = Scale "Contrast" 0 32767 prefs.VIDEO_CONTRAST;
 
101
                        hue = Scale "Hue" 0 32767 prefs.VIDEO_HUE;
 
102
                        frames = Scale "Frames to average" 0 100 prefs.VIDEO_FRAMES;
 
103
                        mono = Toggle "Monochrome grab" prefs.VIDEO_MONO;
 
104
                        crop = Toggle "Crop image" prefs.VIDEO_CROP;
 
105
 
 
106
                        // grab, but hide it ... if we let the crop edit
 
107
                        _raw_grab = Image (im_video_v4l1 device channel.value
 
108
                                b.value col.value con.value 
 
109
                                hue.value frames.value);
 
110
 
 
111
                        edit_crop
 
112
                                = Region _raw_grab left top width height
 
113
                        {
 
114
                                left = prefs.VIDEO_CROP_LEFT;
 
115
                                top = prefs.VIDEO_CROP_TOP;
 
116
                                width = min_pair 
 
117
                                        prefs.VIDEO_CROP_WIDTH (_raw_grab.width + left);
 
118
                                height = min_pair
 
119
                                        prefs.VIDEO_CROP_HEIGHT (_raw_grab.height + top);
 
120
                        }
 
121
 
 
122
                        aspect_ratio = Expression "Stretch vertically by"
 
123
                                prefs.VIDEO_ASPECT;
 
124
 
 
125
                        _result 
 
126
                                = frame'
 
127
                        {
 
128
                                frame 
 
129
                                        = edit_crop, crop
 
130
                                        = _raw_grab;
 
131
 
 
132
                                frame' 
 
133
                                        = colour_transform_to Image_type.B_W frame, mono
 
134
                                        = frame;
 
135
                        }
 
136
                }
 
137
        }
 
138
 
 
139
        Smooth_image_item = class 
 
140
                Menuaction "_Smooth" "remove small features from image" {
 
141
                action in = class
 
142
                        _result {
 
143
                        _vislevel = 3;
 
144
 
 
145
                        feature = Scale "Minimum feature size" 1 50 20;
 
146
 
 
147
                        _result = map_unary (smooth feature.value) in;
 
148
                }
 
149
        }
 
150
 
 
151
        Light_correct_item = class
 
152
                Menuaction "_Flatfield" "use white image w to flatfield image i" {
 
153
                action w i
 
154
                        = map_binary wc w i
 
155
                {
 
156
                        wc w i
 
157
                                = clip2fmt i.format (w' * i)
 
158
                        {
 
159
                                fac = mean w / max w;
 
160
                                w' = fac * (max w / w);
 
161
                        }
 
162
                }
 
163
        }
 
164
 
 
165
        Image_rank_item = Filter_rank_item.Image_rank_item;
 
166
 
 
167
        Tilt_item = Filter_tilt_item;
 
168
 
 
169
        sep1 = Menuseparator;
 
170
 
 
171
        White_balance_item = class
 
172
                Menuaction "_White Balance" 
 
173
                        "use average of small image to set white of large image" {
 
174
                action a b = class
 
175
                        _result {
 
176
                        _vislevel = 3;
 
177
 
 
178
                        white_hint = "Set image white to:";
 
179
                        white = Colour_picker "Lab" [100, 0, 0];
 
180
 
 
181
                        _result
 
182
                                        = map_binary wb a b
 
183
                        {
 
184
                                wb a b
 
185
                                        = colour_transform_to (get_type image) image_xyz'
 
186
                                {
 
187
                                        area x = x.width * x.height;
 
188
                                        larger x y = area x > area y;
 
189
                                        [image, patch] = sortc larger [a, b];
 
190
                                        to_xyz = colour_transform_to Image_type.XYZ;
 
191
                        
 
192
                                        // white balance in XYZ
 
193
                                        patch_xyz = to_colour (to_xyz patch);
 
194
                                        white_xyz = to_xyz white;
 
195
 
 
196
                                        facs = (mean patch_xyz / mean white_xyz) * 
 
197
                                                (white_xyz / patch_xyz);
 
198
 
 
199
                                        image_xyz = to_xyz image;
 
200
                                        image_xyz' = image_xyz * facs;
 
201
                                }
 
202
                        }
 
203
                }
 
204
        }
 
205
 
 
206
        Gamma_item = Image_levels_item.Gamma_item;
 
207
 
 
208
        Tone_item = Image_levels_item.Tone_item;
 
209
 
 
210
        sep2 = Menuseparator;
 
211
 
 
212
        Crop_item = Image_crop_item;
 
213
 
 
214
        Rotate_item = Image_transform_item.Rotate_item;
 
215
 
 
216
        Flip_item = Image_transform_item.Flip_item;
 
217
 
 
218
        Resize_item = Image_transform_item.Resize_item;
 
219
 
 
220
        Rubber_item = Image_transform_item.Image_rubber_item;
 
221
 
 
222
        sep3 = Menuseparator;
 
223
 
 
224
        ICC_item = Colour_icc_item;
 
225
 
 
226
        Temp_item = Colour_temperature_item;
 
227
 
 
228
        Find_calib_item = class 
 
229
                Menuaction "Find _Colour Calibration" 
 
230
                        "find an RGB -> XYZ transform from an image of a colour chart" {
 
231
                action image = class
 
232
                        _result {
 
233
                        _check_args = [
 
234
                                [image, "image", check_Image]
 
235
                        ];
 
236
                        _vislevel = 3;
 
237
 
 
238
                        // get macbeth data file to use
 
239
                        macbeth = Pathname "Pick a Macbeth data file" 
 
240
                                "$VIPSHOME/share/$PACKAGE/data/macbeth_lab_d65.mat";
 
241
 
 
242
                        mode = Option "Input LUT" [
 
243
                                "Linear input",
 
244
                                "Fit intercept from chart greyscale",
 
245
                                "Linearize input from chart greyscale"
 
246
                        ] 2;
 
247
 
 
248
                        // get max of input image
 
249
                        _max_value = Image_format.maxval image.format;
 
250
 
 
251
                        // measure chart image
 
252
                        _camera = measure 0 0 image.width image.height 6 4 image.value;
 
253
 
 
254
                        // load true values
 
255
                        _true_Lab = Matrix_file macbeth.value;
 
256
                        _true_XYZ = colour_transform 
 
257
                                Image_type.LAB Image_type.XYZ _true_Lab;
 
258
 
 
259
                        // get Ys of greyscale
 
260
                        _true_grey_Y = map (extract 1) (drop 18 _true_XYZ.value);
 
261
 
 
262
                        // camera greyscale (all bands)
 
263
                        _camera_grey = drop 18 _camera.value;
 
264
 
 
265
                        // normalise both to 0-1 and combine
 
266
                        _camera_grey' = map (map (multiply (1 / _max_value))) _camera_grey;
 
267
                        _true_grey_Y' = map (multiply (1 / 100)) _true_grey_Y;
 
268
                        _comb 
 
269
                                = Matrix [[0, 0], [1, 1]], mode == 0
 
270
                                = Matrix [0: intercepts, replicate (_camera.width + 1) 1], 
 
271
                                        mode == 1
 
272
                                = Matrix (map2 cons _true_grey_Y' _camera_grey')
 
273
                        {
 
274
                                intercepts = [(linreg _true_grey_Y' cam).intercept :: 
 
275
                                        cam <- transpose _camera_grey'];
 
276
                        }
 
277
 
 
278
                        // make a linearising lut ... zero on left
 
279
                        _linear_lut = im_invertlut _comb (_max_value + 1);
 
280
 
 
281
                        // and display it
 
282
                        // plot from 0 explicitly so we see the effect of mode1 (intercept
 
283
                        // from greyscale)
 
284
                        linearising_lut = Plot [$ymin => 0] _linear_lut;
 
285
 
 
286
                        // map the original image through the lineariser to 
 
287
                        // get linear 0-1 RGB image
 
288
                        _image' = hist_map linearising_lut.value image.value;
 
289
 
 
290
                        // remeasure and solve for RGB -> XYZ
 
291
                        _camera' = im_measure _image' 0 0 image.width image.height 6 4;
 
292
                        _pinv = (transpose _camera' * _camera') ** -1;
 
293
                        M = transpose (_pinv * transpose _camera' * _true_XYZ);
 
294
 
 
295
                        // convert linear RGB camera to Lab 
 
296
                        _result = (Image @
 
297
                                colour_transform Image_type.XYZ Image_type.LAB @
 
298
                                cast_float @
 
299
                                recomb M) _image';
 
300
 
 
301
                        // measure again and compute dE76
 
302
                        _camera'' = im_measure _result.value 0 0 
 
303
                                image.width image.height 6 4;
 
304
 
 
305
                        _dEs = map abs_vec (_camera'' - _true_Lab).value;
 
306
                        final_dE76 = mean _dEs;
 
307
                        _max_dE = foldr max_pair 0 _dEs;
 
308
                        _worst = index (equal _max_dE) _dEs;
 
309
                        worst_patch 
 
310
                                = name _worst ++ " (patch " ++ 
 
311
                                        print (_worst + 1) ++ ", " ++ 
 
312
                                        print _max_dE ++ " dE)"
 
313
                        {
 
314
                                name i 
 
315
                                        = macbeth_names?i, i >= 0 && i < len macbeth_names
 
316
                                        = "Unknown";
 
317
                        }
 
318
                }
 
319
        }
 
320
 
 
321
        Apply_calib_item = class 
 
322
                Menuaction "_Apply Colour Calibration" 
 
323
                        "apply an RGB -> LAB transform to an image" {
 
324
                action a b = class
 
325
                        (map_binary process a b) {
 
326
                        process a b
 
327
                                = result, is_instanceof calib_name calib && is_Image image
 
328
                                = error (_ "bad arguments to " ++ "Calibrate_image")
 
329
                        {
 
330
                                // the name of the calib object we need
 
331
                                calib_name = "Tasks_capture_item.Find_calib_item.action";
 
332
 
 
333
                                // get the Calibrate_chart arg first
 
334
                                [image, calib] = sortc (const (is_instanceof calib_name)) 
 
335
                                        [a, b];
 
336
 
 
337
                                // map the original image through the lineariser to get 
 
338
                                // linear 0-1 RGB image
 
339
                                image' = hist_map calib.linearising_lut image;
 
340
 
 
341
                                // convert linear RGB camera to Lab 
 
342
                                result = colour_transform Image_type.XYZ Image_type.LAB 
 
343
                                        ((float) (recomb calib.M image'));
 
344
                        }
 
345
                }
 
346
        }
 
347
 
 
348
        sep4 = Menuseparator;
 
349
 
 
350
        Graph_hist_item = Hist_find_item;
 
351
 
 
352
        Graph_bands_item = class
 
353
                Menuaction "Plot _Bands" "show image bands as a graph" {
 
354
                action x = class
 
355
                        _result {
 
356
                        _vislevel = 3;
 
357
 
 
358
                        style = Option_enum Plot_style.names "Style" "Line";
 
359
 
 
360
                        auto = Toggle "Auto Range" true;
 
361
                        ymin = Expression "Y range minimum" 0;
 
362
                        ymax = Expression "Y range maximum" 1;
 
363
 
 
364
                        _result
 
365
                                = Plot options (to_image (bands (image x))).value
 
366
                        {
 
367
                                options
 
368
                                        = [$style => style.value] ++ 
 
369
                                                if auto then [] else 
 
370
                                                        [$ymin => ymin.expr, $ymax => ymax.expr]; 
 
371
 
 
372
                                // try to make something image-like from it
 
373
                                image x
 
374
                                        = extract_area x.left x.top 1 1 x.image, is_Mark x
 
375
                                        = get_image x, has_image x
 
376
                                        = get_image (to_image x);
 
377
 
 
378
                                // get as [[1],[2],[3]]
 
379
                                bands x
 
380
                                        = transpose [map mean (bandsplit x)];
 
381
                        }
 
382
                }
 
383
        }
 
384
}
 
385
 
 
386
Tasks_mosaic_item = class
 
387
        Menupullright "_Mosaic" "build image mosaics" {
 
388
        /* Check and group a point list by image.
 
389
         */
 
390
        mosaic_sort_test l
 
391
                = error "mosaic: not all points",
 
392
                        !is_listof is_Mark l
 
393
                = error "mosaic: points not on two images",
 
394
                        !is_list_len 2 images
 
395
                = error "mosaic: images do not match in format and coding",
 
396
                        !all_equal (map get_format l) || !all_equal (map get_coding l)
 
397
                = error "mosaic: not same number of points on each image",
 
398
                        !foldr1 equal (map len l') 
 
399
                = l'
 
400
        {
 
401
                // test for all elements of a list equal
 
402
                all_equal l = all (map (equal (hd l)) (tl l));
 
403
        
 
404
                // all the different images
 
405
                images = mkset pointer_equal (map get_image l);
 
406
        
 
407
                // find all points defined on image
 
408
                test_image image p = (get_image p) === image;
 
409
                find l image = filter (test_image image) l;
 
410
        
 
411
                // group point list by image
 
412
                l' = map (find l) images;
 
413
        }
 
414
 
 
415
        /* Sort a point group to get right before left, and within each group to 
 
416
         * get above before below.
 
417
         */
 
418
        mosaic_sort_lr l
 
419
                = l''
 
420
        {
 
421
                // sort to get upper point first
 
422
                above a b = a.top < b.top;
 
423
                l' = map (sortc above) l;
 
424
        
 
425
                // sort to get right group before left group
 
426
                right a b = a?0.left > b?0.left;
 
427
                l'' = sortc right l';
 
428
        }
 
429
 
 
430
        /* Sort a point group to get top before bottom, and within each group to 
 
431
         * get left before right.
 
432
         */
 
433
        mosaic_sort_tb l
 
434
                = l''
 
435
        {
 
436
                // sort to get upper point first
 
437
                left a b = a.left < b.left;
 
438
                l' = map (sortc left) l;
 
439
        
 
440
                // sort to get right group before left group
 
441
                below a b = a?0.top > b?0.top;
 
442
                l'' = sortc below l';
 
443
        }
 
444
        
 
445
        /* Put 'em together! Group by image, sort vertically (or horizontally) with
 
446
         * one of the above, transpose to get pairs matched up, and flatten again.
 
447
         */
 
448
        mosaic_sort fn = concat @ transpose @ fn @ mosaic_sort_test;
 
449
 
 
450
        Mosaic_1point_item = class 
 
451
                Menupullright "_One Point" "join two images with a single tie point" {
 
452
                check_ab_args a b = [
 
453
                        [a, "a", check_Mark],
 
454
                        [b, "b", check_Mark]
 
455
                ];
 
456
        
 
457
                // shortcut to prefs
 
458
                prefs = Workspaces.Preferences;
 
459
                search_area = prefs.MOSAIC_WINDOW_SIZE;
 
460
                object_size = prefs.MOSAIC_OBJECT_SIZE;
 
461
                blend_width_widget = Scale "Maximum blend width" 0 100 prefs.MOSAIC_MAX_BLEND_WIDTH;
 
462
                refine_widget = Toggle "Refine selected tie-points" prefs.MOSAIC_REFINE;
 
463
 
 
464
                lr_mos _refine a b = class 
 
465
                        Image _result {
 
466
                        _check_args = check_ab_args a b;
 
467
        
 
468
                        bw = blend_width_widget;
 
469
                        refine = _refine;
 
470
        
 
471
                        _result 
 
472
                                = im_lrmosaic a'.image.value b'.image.value 0 
 
473
                                        a'.left a'.top b'.left b'.top
 
474
                                        (object_size / 2) (search_area / 2) 0 bw.value,
 
475
                                                refine
 
476
                                = im_lrmerge a'.image.value b'.image.value
 
477
                                        (b'.left - a'.left) (b'.top - a'.top) bw.value
 
478
                        {
 
479
                                [a', b'] = mosaic_sort mosaic_sort_lr [a, b];
 
480
                        }
 
481
                }
 
482
 
 
483
                tb_mos _refine a b = class
 
484
                        Image _result {
 
485
                        _check_args = check_ab_args a b;
 
486
        
 
487
                        bw = blend_width_widget;
 
488
                        refine = _refine;
 
489
        
 
490
                        _result 
 
491
                                = im_tbmosaic a'.image.value b'.image.value 0 
 
492
                                        a'.left a'.top b'.left b'.top
 
493
                                        (object_size / 2) (search_area / 2) 0 bw.value,
 
494
                                                refine
 
495
                                = im_tbmerge a'.image.value b'.image.value
 
496
                                        (b'.left - a'.left) (b'.top - a'.top) bw.value
 
497
                        {
 
498
                                [a', b'] = mosaic_sort mosaic_sort_tb [a, b];
 
499
                        }
 
500
                }
 
501
 
 
502
                Left_right_item = class 
 
503
                        Menuaction "_Left to Right" 
 
504
                                "join two images left-right with a single tie point" {
 
505
                        action a b = lr_mos refine_widget a b;
 
506
                }
 
507
 
 
508
                Top_bottom_item = class 
 
509
                        Menuaction "_Top to Bottom" 
 
510
                                "join two images top-bottom with a single tie point" {
 
511
                        action a b = tb_mos refine_widget a b;
 
512
                }
 
513
        
 
514
                sep1 = Menuseparator;
 
515
 
 
516
                Left_right_manual_item = class 
 
517
                        Menuaction "Manual L_eft to Right" 
 
518
                                "join left-right, no auto-adjust of tie points" {
 
519
                        action a b = lr_mos false a b;
 
520
                }
 
521
 
 
522
                Top_bottom_manual_item = class 
 
523
                        Menuaction "Manual T_op to Bottom" 
 
524
                                "join top-bottom, no auto-adjust of tie points" {
 
525
                        action a b = tb_mos false a b;
 
526
                }
 
527
        }
 
528
 
 
529
        Mosaic_2point_item = class 
 
530
                Menupullright "_Two Point" "join two images with two tie points" {
 
531
                check_abcd_args a b c d = [
 
532
                        [a, "a", check_Mark],
 
533
                        [b, "b", check_Mark],
 
534
                        [c, "c", check_Mark],
 
535
                        [d, "d", check_Mark]
 
536
                ];
 
537
        
 
538
                // shortcut to prefs
 
539
                prefs = Workspaces.Preferences;
 
540
                search_area = prefs.MOSAIC_WINDOW_SIZE;
 
541
                object_size = prefs.MOSAIC_OBJECT_SIZE;
 
542
                blend_width_widget = Scale "Maximum blend width" 0 100 prefs.MOSAIC_MAX_BLEND_WIDTH;
 
543
                refine_widget = Toggle "Refine selected tie-points" prefs.MOSAIC_REFINE;
 
544
 
 
545
                Left_right_item = class 
 
546
                        Menuaction "_Left to Right" 
 
547
                                "join two images left-right with a pair of tie points" {
 
548
                        action a b c d = class 
 
549
                                Image _result {
 
550
                                _check_args = check_abcd_args a b c d;
 
551
        
 
552
                                bw = blend_width_widget;
 
553
                                refine = refine_widget;
 
554
        
 
555
                                _result 
 
556
                                        = im_lrmosaic1 a'.image.value b'.image.value 0
 
557
                                                a'.left a'.top b'.left b'.top
 
558
                                                c'.left c'.top d'.left d'.top
 
559
                                                (object_size / 2) (search_area / 2)
 
560
                                                0 bw.value,
 
561
                                                        refine
 
562
                                        = im_lrmerge1 a'.image.value b'.image.value
 
563
                                                a'.left a'.top b'.left b'.top
 
564
                                                c'.left c'.top d'.left d'.top
 
565
                                                bw.value
 
566
                                {
 
567
                                        [a', b', c', d'] = mosaic_sort mosaic_sort_lr [a, b, c, d];
 
568
                                }
 
569
                        }
 
570
                }
 
571
 
 
572
                Top_bottom_item = class 
 
573
                        Menuaction "_Top to Bottom" 
 
574
                                "join two images top-bottom with a pair of tie points" {
 
575
                        action a b c d = class 
 
576
                                Image _result {
 
577
                                _check_args = check_abcd_args a b c d;
 
578
        
 
579
                                bw = blend_width_widget;
 
580
                                refine = refine_widget;
 
581
        
 
582
                                _result 
 
583
                                        = im_tbmosaic1 a'.image.value b'.image.value 0
 
584
                                                a'.left a'.top b'.left b'.top
 
585
                                                c'.left c'.top d'.left d'.top
 
586
                                                (object_size / 2) (search_area / 2)
 
587
                                                0 bw.value,
 
588
                                                        refine
 
589
                                        = im_tbmerge1 a'.image.value b'.image.value
 
590
                                                a'.left a'.top b'.left b'.top
 
591
                                                c'.left c'.top d'.left d'.top
 
592
                                                bw.value
 
593
                                {
 
594
                                        [a', b', c', d'] = mosaic_sort mosaic_sort_tb [a, b, c, d];
 
595
                                }
 
596
                        }
 
597
                }
 
598
        }
 
599
        
 
600
        sep1 = Menuseparator;
 
601
 
 
602
        Balance_item = class 
 
603
                Menuaction "Mosaic _Balance" 
 
604
                        "disassemble mosaic, scale brightness to match, reassemble" {
 
605
                action x 
 
606
                        = map_unary balance x
 
607
                {
 
608
                        balance x
 
609
                                = oo_unary_function balance_op x, is_class x
 
610
                                = im_global_balancef x 
 
611
                                        Workspaces.Preferences.MOSAIC_BALANCE_GAMMA, 
 
612
                                        is_image x
 
613
                                = error (_ "bad arguments to " ++ "balance")
 
614
                        {
 
615
                                balance_op = Operator "balance" balance 
 
616
                                        Operator_type.COMPOUND_REWRAP false;
 
617
                        }
 
618
                }
 
619
        }
 
620
 
 
621
////////////////////////////////////////////////////////////////////////////////////
 
622
////////////////////////////////////////////////////////////////////////////////////
 
623
Manual_balance_item = class
 
624
        Menupullright "Manual B_alance" "balance tonality of user defined areas" {
 
625
        prefs = Workspaces.Preferences;
 
626
        
 
627
        ////////////////////////////////////////////////////////////////////////////////////
 
628
        Balance_find_item = class
 
629
                Menuaction "_Find Values"
 
630
                         "calculates values required to scale and offset balance user defined areas in a given image"
 
631
                         /* Outputs a matrix of scale and offset values. Eg. Values required to balance the secondary 
 
632
                          * structure in an X-ray image.  Takes an X-ray image an 8-bit control mask and a list of 
 
633
                          * 8-bit reference masks, where the masks are white on a black background.
 
634
                          */
 
635
        {
 
636
                action im_in m_control m_group = class
 
637
                        Matrix values{
 
638
                        _vislevel = 1;
 
639
 
 
640
                        _control_im = if m_control then im_in else 0;
 
641
                        _control_meanmax = so_meanmax _control_im;
 
642
                        _group_check = is_Group m_group;
 
643
                        _m_list = m_group.value, _group_check
 
644
                                = m_group;
 
645
 
 
646
                        process m_current mat_in = mat_out
 
647
                                {so_values  = so_calculate _control_meanmax im_in m_current;
 
648
                                 mat_out = join [so_values] mat_in;}
 
649
                
 
650
                        values = (foldr process [] _m_list);
 
651
                }
 
652
        }
 
653
        
 
654
        ////////////////////////////////////////////////////////////////////////////////////
 
655
        Balance_check_item = class 
 
656
                Menuaction "_Check Values"
 
657
                         "allows calculated set of scale and offset values to be checked and adjusted if required" 
 
658
                         /* Outputs adjusted matrix of scale and offset values and scale and offset image maps.
 
659
                          * Eg. Check values required to balance the secondary structure in an X-ray image.  
 
660
                          * Takes an X-ray image an 8-bit control mask and a list of 8-bit reference masks, 
 
661
                          * where the masks are white on a black background. 
 
662
                          */
 
663
        {
 
664
                action im_in m_matrix m_group = class
 
665
                        Image value 
 
666
                        {
 
667
                        _vislevel = 3;
 
668
                        
 
669
                        blur = Scale "Blur" 1 10 1;
 
670
                        _blur = (blur.value/2 + 0.5), blur.value > 1
 
671
                                  =  1;
 
672
                
 
673
                        _group_check = is_Group m_group;
 
674
                        _m_list = m_group.value, _group_check
 
675
                                = m_group;
 
676
                                                
 
677
                        adjust = Matrix_rec mat_a
 
678
                                {
 
679
                                no_masks = len _m_list;
 
680
                                mat_a = replicate no_masks [0, 0];
 
681
                                }
 
682
                        
 
683
                // Apply the user defined adjustments to the inputted matrix of scale and offset values  
 
684
                        _adjusted = map2 fn_adjust m_matrix.value adjust.value;
 
685
                                fn_adjust a b = [(a?0 + b?0), (a?1 + (a?1 * b?1))];
 
686
                                
 
687
                        _scaled_ims = map (fn_so_apply im_in) _adjusted;
 
688
                                fn_so_apply im so = map_unary adj im
 
689
                                        {adj im = im * (so?0) + (so?1);}                        
 
690
                        _im_pairs = zip2 _m_list _scaled_ims;
 
691
                        
 
692
                // Prepare black images as starting point. ////////////
 
693
                        _blank = image_new (_m_list?0).width (_m_list?0).height 1 6 Image_coding.NOCODING 1 0 0 0;
 
694
                        _pair_start = [(_blank + 1), _blank];
 
695
                        
 
696
                        Build = Toggle "Build Scale and Offset Correction Images" false;
 
697
                        
 
698
                        Output = class
 
699
                                { 
 
700
                                _vislevel = 1;
 
701
                                scale_im = _build?0;
 
702
                                offset_im = _build?1;   
 
703
                                so_values = Matrix _adjusted;
 
704
                                
 
705
                                _build = [Image so_images?0, Image so_images?1], Build
 
706
                                       = ["Scale image not built.", "Offset image not built."]
 
707
                                        {
 
708
                                        m_list' = transpose [_m_list];                  
 
709
                                        m_all = map2 join m_list' _adjusted;                                    
 
710
                                        so_images = foldr process_2 _pair_start m_all;                                  
 
711
                                        }
 
712
                                }
 
713
                                  
 
714
                        value = (foldr process_1 im_in_b _im_pairs).value
 
715
                                {im_in_b = map_unary cast_float im_in;}
 
716
                                
 
717
                        process_1 m_current im_start 
 
718
                                = im_out
 
719
                                { 
 
720
                                bl_mask    = convsep (matrix_blur _blur) (get_image m_current?0);
 
721
                                blended_im  = im_blend bl_mask (m_current?1).value im_start.value;
 
722
                                im_out      = Image (clip2fmt im_start.format blended_im);
 
723
                                }                       
 
724
                        
 
725
                        // Process for building scale and offset image. 
 
726
                        process_2 current p_start 
 
727
                                = p_out
 
728
                                { 
 
729
                                im_s = if ((current?0) > 128) then current?1 else _blank;
 
730
                                im_o = if ((current?0) > 128) then current?2 else _blank;
 
731
                                
 
732
                                im_s' = convsep (matrix_blur _blur) (im_s != 0);
 
733
                                im_o' = convsep (matrix_blur _blur) (im_o != 0);
 
734
                                
 
735
                                im_s'' = im_blend im_s'.value im_s.value p_start?0;
 
736
                                im_o'' = im_blend im_o'.value im_o.value p_start?1;
 
737
                                
 
738
                                p_out  = [im_s'', im_o''];
 
739
                                }
 
740
                }
 
741
        }
 
742
        
 
743
        ////////////////////////////////////////////////////////////////////////////////////
 
744
        Balance_apply_item = class 
 
745
                Menuaction "_Apply Values" 
 
746
                         "apply scale and offset corrections, defined as image maps, to a given image" 
 
747
                         /* Outputs the balanced image. Eg. Balance the secondary structure in an X-ray image.  Takes an 
 
748
                          * X-ray image an 32-bit float scale image and a 32-bit offset image.
 
749
                          */
 
750
        {
 
751
                action im_in scale_im offset_im = class
 
752
                        Image value 
 
753
                        {
 
754
                        _vislevel = 1;
 
755
 
 
756
                        xfactor = im_in.width/scale_im.width;
 
757
                        yfactor = im_in.height/scale_im.height;
 
758
                        
 
759
                        _scale_im = resize xfactor yfactor 1 scale_im;
 
760
                        _offset_im = resize xfactor yfactor 1 offset_im;
 
761
                        
 
762
                        value = get_image ( clip2fmt im_in.format ( ( im_in * _scale_im ) +  _offset_im ) );    
 
763
                        }
 
764
                }
 
765
}
 
766
 
 
767
    Tilt_item = Filter_tilt_item;
 
768
 
 
769
        sep2 = Menuseparator;
 
770
 
 
771
        Rebuild_item = class 
 
772
                Menuaction "_Rebuild" 
 
773
                        "disassemble mosaic, substitute image files and reassemble" {
 
774
                action x = class 
 
775
                        _result {
 
776
                        _vislevel = 3;
 
777
        
 
778
                        old = String "In each filename, replace" "foo";
 
779
                        new = String "With" "bar";
 
780
        
 
781
                        _result
 
782
                                = map_unary remosaic x
 
783
                        {
 
784
                                remosaic image 
 
785
                                        = Image (im_remosaic image.value old.value new.value);
 
786
                        }
 
787
                }
 
788
        }
 
789
 
 
790
        sep3 = Menuseparator;
 
791
 
 
792
Clone_area_item = class
 
793
   Menuaction "_Clone Area"
 
794
       "replace dark or light section of im1 with pixels from im2"
 
795
   {
 
796
   action im1 im2 = class
 
797
       _result {
 
798
       _check_args = [
 
799
           [im1, "im1", check_Image],
 
800
           [im2, "im2", check_Image]
 
801
       ];
 
802
                 _vislevel = 3;                            /* Region on first
 
803
image placed in the top left hand corner,
 
804
        * positioned and size relative to the height and width of im1.
 
805
        */
 
806
       r1 = Region_relative im1 0.05 0.05 0.05 0.05;
 
807
             /* Mark on second image placed in the top left hand corner,
 
808
        * positioned relative to the height and width of im2. Used to
 
809
        * define _r2, the region from which the section of image is cloned
 
810
        * from.
 
811
        */
 
812
       p2 = Mark_relative im2 0.05 0.05;              _r2 = Region im2 p2.left
 
813
p2.top r1.width r1.height;
 
814
             mask = [r1 <= Options.sc, r1 >=
 
815
Options.sc]?(Options.replace);
 
816
                 Options = class
 
817
           {
 
818
           _vislevel = 3;
 
819
                     pause = Toggle "Pause process" true;
 
820
                         /* Option toggle used to define whether the user is
 
821
            * replacing a dark or a light area.
 
822
            */
 
823
           replace = Option "Replace" [ "A Dark Area", "A Light Area" ] 1;
 
824
 
 
825
           // Used to select the area to be replaced.
 
826
            sc = Scale "Scale cutoff" 0.01 mx (mx / 2)
 
827
               {mx = Image_format.maxval im1.format;}
 
828
             //Allows replacement with scale&offset balanced gaussian noise.
 
829
           balance = Toggle "Balance cloned data to match surroundings." true;
 
830
                             //Allows replacement with scale&offset balanced
 
831
                             //gaussian noise.
 
832
           process = Toggle "Replace area with Gaussian noise." false;
 
833
           }
 
834
                     _result    = im1, Options.pause
 
835
               = Image (im_insert im1.value patch r1.left r1.top)
 
836
           {              r2 = Region im2 p2.left p2.top r1.width r1.height;
 
837
           ref_meanmax = so_meanmax (if mask then 0 else r1);
 
838
                     mask8 = Matrix_mor [[255, 255, 255], [255, 255, 255],
 
839
[255, 255, 255]];
 
840
           mask_a = map_unary (dilate mask8) mask;
 
841
           mask_b = convsep (matrix_blur 2) mask_a;
 
842
                     patch = so_balance ref_meanmax r1 r2 mask_b
 
843
Options.process, Options.balance
 
844
                 = so_balance ref_meanmax r1 r2 mask_b Options.process,
 
845
Options.process
 
846
                 = im_blend (get_image mask_b) (get_image r2) (get_image r1);
 
847
           }
 
848
       }
 
849
   } 
 
850
}
 
851
 
 
852
Tasks_frame_item = Frame_item;
 
853
 
 
854
Tasks_print_item = class
 
855
        Menupullright "_Print" "useful stuff for image output" {
 
856
 
 
857
        Rotate_item = Image_transform_item.Rotate_item;
 
858
 
 
859
        Flip_item = Image_transform_item.Flip_item;
 
860
 
 
861
        Resize_item = Image_transform_item.Resize_item;
 
862
 
 
863
        Tone_item = Image_levels_item.Tone_item; 
 
864
 
 
865
        Sharpen_item = class 
 
866
                Menuaction "_Sharpen" 
 
867
                        "unsharp filter tuned for typical inkjet printers" {
 
868
                action x = class 
 
869
                        _result {
 
870
                        _vislevel = 3;
 
871
        
 
872
                        target_dpi = Option "Sharpen for print at" [
 
873
                                "400 dpi",
 
874
                                "300 dpi",
 
875
                                "150 dpi",
 
876
                                "75 dpi"
 
877
                        ] 1;
 
878
        
 
879
                        _result
 
880
                                = map_unary process x
 
881
                        {
 
882
                                process image
 
883
                                        = sharpen params?0 params?1 
 
884
                                                params?2 params?3 params?4 params?5
 
885
                                                (colour_transform_to Image_type.LABQ image)
 
886
                                {
 
887
                                        // sharpen params for various dpi
 
888
                                        // just change the size of the area we search
 
889
                                        param_table = [
 
890
                                                [7, 2.5, 40, 20, 0.5, 1.5],
 
891
                                                [5, 2.5, 40, 20, 0.5, 1.5],
 
892
                                                [3, 2.5, 40, 20, 0.5, 1.5],
 
893
                                                [11, 2.5, 40, 20, 0.5, 1.5]
 
894
                                        ];
 
895
                                        params = param_table?target_dpi;
 
896
                                }
 
897
                        }
 
898
                }
 
899
        }
 
900
 
 
901
        sep1 = Menuseparator;
 
902
 
 
903
        Temp_item = Colour_temperature_item;
 
904
 
 
905
        ICC_item = Colour_icc_item;
 
906
}