2
Menupullright "_New" "new histogram" {
4
Menuaction "Histogram" "make an identity histogram" {
9
d = Option "Depth" ["8 bit", "16 bit"] 0;
10
_result = Plot [] ([im_identity 1, im_identity_ushort 1 65536]?d);
14
Hist_new_from_matrix = Matrix_buildlut_item;
16
Hist_from_image_item = class
17
Menuaction "Ta_g Image As Histogram" "set image Type field to Histogram" {
18
action x = hist_tag x;
22
Menuaction "_Tone Curve" "make a new tone mapping curve" {
27
d = Option "Depth" ["8 bit", "16 bit"] 0;
28
b = Scale "Black point" 0 100 0;
29
w = Scale "White point" 0 100 100;
31
sp = Scale "Shadow point" 0.1 0.3 0.2;
32
mp = Scale "Mid-tone point" 0.4 0.6 0.5;
33
hp = Scale "Highlight point" 0.7 0.9 0.8;
35
sa = Scale "Shadow adjust" (-15) 15 0;
36
ma = Scale "Mid-tone adjust" (-30) 30 0;
37
ha = Scale "Highlight adjust" (-15) 15 0;
40
= tone_build fmt b w sp mp hp sa ma ha
42
fmt = [Image_format.UCHAR, Image_format.USHORT]?d;
48
Hist_find_item = class
49
Menupullright "_Find" "find a histogram" {
51
Menuaction "_One Dimension"
52
"for a n-band image, make an n-band 1D histogram" {
53
action x = map_unary hist_find x;
57
Menuaction "_Many Dimensions"
58
"for a n-band image, make an n-dimensional histogram" {
63
// default to something small-ish
64
bins = Expression "Number of bins in each dimension" 8;
70
= hist_find_nD bins in;
77
Menuaction "_Map Histogram" "map an image through a histogram" {
84
[im, hist] = sortc (const is_hist) [a, b];
89
Hist_eq_item = Filter_enhance_item.Hist_equal_item;
94
Menuaction "_Cumulativise Histogram"
95
"form cumulative histogram" {
96
action x = map_unary hist_cum x;
99
Hist_diff_item = class
100
Menuaction "_Differentiate Histogram"
101
"find point-to-point differences (inverse of Cumulativise)" {
102
action x = map_unary hist_diff x;
105
Hist_norm_item = class
106
Menuaction "N_ormalise Histogram" "normalise a histogram" {
107
action x = map_unary hist_norm x;
110
Hist_match_item = class
111
Menuaction "Ma_tch Histogram"
112
"find LUT which will match first histogram to second" {
113
action in ref = map_binary hist_match in ref;
116
Hist_zerox_item = class
117
Menuaction "_Zero Crossings" "find zero crossings" {
122
edge = Option "Direction" [
128
= map_unary (zerox (if edge == 0 then -1 else 1)) x;
134
Hist_profile_item = class
135
Menuaction "Find _Profile"
136
"search from image edges for non-zero pixels" {
141
edge = Option "Search from" [
143
"Left edge to right",
149
= map_unary profile x
152
= (Plot_histogram @ hist_tag) [
153
profilemb 0 image.value,
154
profilemb 1 image.value,
155
profilemb 0 (fliptb image.value),
156
profilemb 1 (fliplr image.value)
159
// im_profile only does 1 band images :-(
160
profilemb d = bandjoin @ map (converse im_profile d) @ bandsplit;
165
Hist_project_item = class
166
Menuaction "Find Pro_jections"
167
"find horizontal and vertical projections" {
171
_result = map_unary project x;
173
// extract the result ... could be a group
175
= Plot_histogram _result?n, is_list _result
176
= Group (map (Plot_histogram @ converse subscript n) _result.value);
180
centre = (gravity horizontal, gravity vertical);
186
Hist_graph_item = class
187
Menuaction "P_lot Slice" "plot a slice along a guide or arrow" {
192
width = Scale "Width" 1 40 1;
193
displace = Scale "Horizontal displace" (-50) 50 0;
194
vdisplace = Scale "Vertical displace" (-50) 50 0;
202
// the line as a polar vector
203
pv = polar (arrow.width, arrow.height);
206
// smallest rotation that will make the line horizontal
212
im' = rotate a' arrow.image;
214
// look at the start and end of the arrow, pick the leftmost
216
= (arrow.left, arrow.top), arrow.left <= arrow.right
217
= (arrow.right, arrow.bottom);
219
// transform that point to im' space
220
p' = rectangular (polar p + (0, a')) +
221
(im'.xoffset, im'.yoffset);
225
(re p' + displace.value)
226
(im p' - width.value / 2 + vdisplace.value)
230
// squish vertically to get an average
231
area' = resize 1 (1 / width.value) Interpolate.BILINEAR area;
237
Extract_arrow_item = class
238
Menuaction "Extract _Arrow" "extract the area around an arrow" {
243
width = Scale "Width" 1 40 1;
244
displace = Scale "Horizontal displace" (-50) 50 0;
245
vdisplace = Scale "Vertical displace" (-50) 50 0;
253
// the line as a polar vector
254
pv = polar (arrow.width, arrow.height);
257
// smallest rotation that will make the line horizontal
263
im' = rotate a' arrow.image;
265
// look at the start and end of the arrow, pick the leftmost
267
= (arrow.left, arrow.top), arrow.left <= arrow.right
268
= (arrow.right, arrow.bottom);
270
// transform that point to im' space
271
p' = rectangular (polar p + (0, a')) +
272
(im'.xoffset, im'.yoffset);
276
(re p' + displace.value)
277
(im p' - width.value / 2 + vdisplace.value)
285
Hist_plot_item = class
286
Menuaction "Plot _Object"
287
"plot an object as a bar, point or line graph" {
292
format = Option_enum Plot_format.names "Format" "YYYY";
293
style = Option_enum Plot_style.names "Style" "Line";
295
auto = Toggle "Auto Range" true;
296
xmin = Expression "X range minimum" 0;
297
xmax = Expression "X range maximum" 1;
298
ymin = Expression "Y range minimum" 0;
299
ymax = Expression "Y range maximum" 1;
302
= Plot options (image x)
305
= [$style => style.value, $format => format.value] ++ range;
308
= [$xmin => xmin.expr, $xmax => xmax.expr,
309
$ymin => ymin.expr, $ymax => ymax.expr];
312
= image (extract_arrow x), is_Arrow x
313
= get_image x, has_image x
317
im = get_image (to_image x);
322
// matrix to image makes a 1-band mxn image
323
// we need to put columns into bands
325
= bandjoin (map extract_col [0 .. w - 1])
327
extract_col x = extract_area x 0 1 h im;
332
= extract_area (re p') (im p') (re pv) 1 im'
334
// the line as a polar vector
335
pv = polar (arrow.width, arrow.height);
338
// smallest rotation that will make the line horizontal
344
im' = rotate a' arrow.image;
346
// look at the start and end of the arrow, pick the leftmost
348
= (arrow.left, arrow.top), arrow.left <= arrow.right
349
= (arrow.right, arrow.bottom);
351
// transform that point to im' space
352
p' = rectangular (polar p + (0, a')) +
353
(im'.xoffset, im'.yoffset);