1Hist_new_item = class 2 Menupullright "_New" "new histogram" { 3 Hist_item = class 4 Menuaction "_Identity" "make an identity histogram" { 5 action = class 6 _result { 7 _vislevel = 3; 8 9 d = Option "Depth" ["8 bit", "16 bit"] 0; 10 _result = Plot [] ([im_identity 1, im_identity_ushort 1 65536]?d); 11 } 12 } 13 14 Hist_new_from_matrix = Matrix_buildlut_item; 15 16 Hist_from_image_item = class 17 Menuaction "Ta_g Image As Histogram" "set image Type to Histogram" { 18 action x = hist_tag x; 19 } 20 21 Tone_item = class 22 Menuaction "_Tone Curve" "make a new tone mapping curve" { 23 action = class 24 _result { 25 _vislevel = 3; 26 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; 30 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; 34 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; 38 39 _result 40 = tone_build fmt b w sp mp hp sa ma ha 41 { 42 fmt = [Image_format.UCHAR, Image_format.USHORT]?d; 43 } 44 } 45 } 46} 47 48Hist_convert_to_hist_item = class 49 Menuaction "Con_vert to Histogram" "convert anything to a histogram" { 50 action x = hist_tag (to_image x); 51} 52 53Hist_find_item = class 54 Menupullright "_Find" "find a histogram" { 55 Oned_item = class 56 Menuaction "_One Dimension" 57 "for a n-band image, make an n-band 1D histogram" { 58 action x = map_unary hist_find x; 59 } 60 61 Nd_item = class 62 Menuaction "_Many Dimensions" 63 "for a n-band image, make an n-dimensional histogram" { 64 action x = class 65 _result { 66 _vislevel = 3; 67 68 // default to something small-ish 69 bins = Expression "Number of bins in each dimension" 8; 70 71 _result 72 = map_unary process x 73 { 74 process in 75 = hist_find_nD bins in; 76 } 77 } 78 } 79 80 Indexed_item = class 81 Menuaction "_Indexed" 82 "use a 1-band index image to pick bins for an n-band image" { 83 action x y 84 = map_binary map x y 85 { 86 map a b 87 = hist_find_indexed index im 88 { 89 [im, index] = sortc (const is_index) [a, b]; 90 91 is_index x 92 = has_image x && b == 1 && 93 (f == Image_format.UCHAR || f == Image_format.USHORT) 94 { 95 im = get_image x; 96 b = get_bands x; 97 f = get_format x; 98 } 99 } 100 } 101 } 102} 103 104Hist_map_item = class 105 Menuaction "_Map" "map an image through a histogram" { 106 action x y 107 = map_binary map x y 108 { 109 map a b 110 = hist_map hist im 111 { 112 [im, hist] = sortc (const is_hist) [a, b]; 113 } 114 } 115} 116 117Hist_eq_item = Filter_enhance_item.Hist_equal_item; 118 119#separator 120 121Hist_cum_item = class 122 Menuaction "_Integrate" 123 "form cumulative histogram" { 124 action x = map_unary hist_cum x; 125} 126 127Hist_diff_item = class 128 Menuaction "_Differentiate" 129 "find point-to-point differences (inverse of Integrate)" { 130 action x = map_unary hist_diff x; 131} 132 133Hist_norm_item = class 134 Menuaction "N_ormalise" "normalise a histogram" { 135 action x = map_unary hist_norm x; 136} 137 138Hist_inv_item = class 139 Menuaction "In_vert" "invert a histogram" { 140 action x = map_unary hist_inv x; 141} 142 143Hist_match_item = class 144 Menuaction "Ma_tch" 145 "find LUT which will match first histogram to second" { 146 action in ref = map_binary hist_match in ref; 147} 148 149Hist_zerox_item = class 150 Menuaction "_Zero Crossings" "find zero crossings" { 151 action x = class 152 _result { 153 _vislevel = 3; 154 155 edge = Option "Direction" [ 156 "Positive-going", 157 "Negative-going" 158 ] 0; 159 160 _result 161 = map_unary (zerox (if edge == 0 then -1 else 1)) x; 162 } 163} 164 165#separator 166 167Hist_profile_item = class 168 Menuaction "Find _Profile" 169 "search from image edges for non-zero pixels" { 170 action x = class 171 _result { 172 _vislevel = 3; 173 174 edge = Option "Search from" [ 175 "Top edge down", 176 "Left edge to right", 177 "Bottom edge up", 178 "Right edge to left" 179 ] 2; 180 181 _result 182 = map_unary profile x 183 { 184 profile image 185 = (Plot_histogram @ hist_tag) [ 186 profilemb 0 image.value, 187 profilemb 1 image.value, 188 profilemb 0 (fliptb image.value), 189 profilemb 1 (fliplr image.value) 190 ]?edge; 191 192 // im_profile only does 1 band images :-( 193 profilemb d = bandjoin @ map (converse im_profile d) @ bandsplit; 194 } 195 } 196} 197 198Hist_project_item = class 199 Menuaction "Find Pro_jections" 200 "find horizontal and vertical projections" { 201 action x = class { 202 _vislevel = 2; 203 204 _result = map_unary project x; 205 206 // extract the result ... could be a group 207 extr n 208 = Plot_histogram _result?n, is_list _result 209 = Group (map (Plot_histogram @ converse subscript n) _result.value); 210 211 horizontal = extr 0; 212 vertical = extr 1; 213 centre = (gravity horizontal, gravity vertical); 214 } 215} 216 217#separator 218 219Hist_graph_item = class 220 Menuaction "P_lot Slice" "plot a slice along a guide or arrow" { 221 action x = class 222 _value { 223 _vislevel = 3; 224 225 width = Scale "Width" 1 40 1; 226 displace = Scale "Horizontal displace" (-50) 50 0; 227 vdisplace = Scale "Vertical displace" (-50) 50 0; 228 229 _value 230 = map_unary graph x 231 { 232 graph arrow 233 = hist_tag area' 234 { 235 area = extract_arrow 236 displace.value vdisplace.value width.value arrow; 237 238 // squish vertically to get an average 239 area' = resize Kernel_linear 1 (1 / width.value) area; 240 } 241 } 242 } 243} 244 245Extract_arrow_item = class 246 Menuaction "Extract _Arrow" "extract the area around an arrow" { 247 action x = class 248 _value { 249 _vislevel = 3; 250 251 width = Scale "Width" 1 40 1; 252 displace = Scale "Horizontal displace" (-50) 50 0; 253 vdisplace = Scale "Vertical displace" (-50) 50 0; 254 255 _value 256 = map_unary (extract_arrow 257 displace.value vdisplace.value width.value) x; 258 } 259} 260 261Hist_plot_item = class 262 Menuaction "Plot _Object" 263 "plot an object as a bar, point or line graph" { 264 action x = class 265 _result { 266 _vislevel = 3; 267 268 caption = Expression "Chart caption" "none"; 269 format = Option_enum "Format" Plot_format.names "YYYY"; 270 style = Option_enum "Style" Plot_style.names "Line"; 271 272 auto = Toggle "Auto Range" true; 273 xmin = Expression "X range minimum" 0; 274 xmax = Expression "X range maximum" 1; 275 ymin = Expression "Y range minimum" 0; 276 ymax = Expression "Y range maximum" 1; 277 xcaption = Expression "X axis caption" "none"; 278 ycaption = Expression "Y axis caption" "none"; 279 series_captions = Expression "Series captions" ["Band 0"]; 280 281 _result 282 = Plot options (image x) 283 { 284 options 285 = [$style => style.value, $format => format.value] ++ 286 range ++ captions; 287 range 288 = [], auto 289 = [$xmin => xmin.expr, $xmax => xmax.expr, 290 $ymin => ymin.expr, $ymax => ymax.expr]; 291 292 captions 293 = concat (map test caption_options) ++ 294 [$series_captions => series_captions.expr] 295 { 296 caption_options = [ 297 $caption => caption.expr, 298 $xcaption => xcaption.expr, 299 $ycaption => ycaption.expr 300 ]; 301 test x 302 = [], value == "none" 303 = [option_name => value] 304 { 305 [option_name, value] = x; 306 } 307 } 308 309 image x 310 = image (extract_arrow 0 0 1 x), is_Arrow x 311 = get_image x, has_image x 312 = x2b im, b == 1 313 = im 314 { 315 im = get_image (to_image x); 316 w = get_width im; 317 h = get_height im; 318 b = get_bands im; 319 320 // matrix to image makes a 1-band mxn image 321 // we need to put columns into bands 322 x2b im 323 = bandjoin (map extract_col [0 .. w - 1]) 324 { 325 extract_col x = extract_area x 0 1 h im; 326 } 327 } 328 } 329 } 330} 331