1
2Matrix_build_item = class
3	Menupullright "_New" "make a new matrix of some sort" {
4
5	Plain_item = class
6		Menuaction "_Plain" "make a new plain matrix widget" {
7		action = Matrix (identity_matrix 3);
8	}
9
10	Convolution_item = class
11		Menuaction "_Convolution" "make a new convolution matrix widget" {
12		action = Matrix_con 1 0 [[0, 0, 0], [0, 1, 0], [0, 0, 0]];
13	}
14
15	Recombination_item = class
16		Menuaction "_Recombination"
17			"make a new recombination matrix widget" {
18		action = Matrix_rec (identity_matrix 3);
19	}
20
21	Morphology_item = class
22		Menuaction "_Morphology" "make a new morphology matrix widget" {
23		action = Matrix_mor [[0, 0, 0], [0, 255, 0], [0, 0, 0]];
24	}
25
26	sep1 = Menuseparator;
27
28	Matrix_gaussian_item = class
29		Menuaction "_Gaussian" "make a gaussian matrix" {
30		action = class
31			_result {
32			_vislevel = 3;
33
34			sigma = Slider 0.001 10 1;
35			min_amplitude = Slider 0 1 0.2;
36			integer = Toggle "Integer" false;
37
38			_result
39				= fn sigma.value min_amplitude.value
40			{
41				fn
42					= im_gauss_imask, integer
43					= im_gauss_dmask;
44			}
45		}
46	}
47
48	Matrix_laplacian_item = class
49		Menuaction "_Laplacian" "make the Laplacian of a Gaussian matrix" {
50		action = class
51			_result {
52			_vislevel = 3;
53
54			sigma = Slider 0.001 10 1.5;
55			min_amplitude = Slider 0 1 0.1;
56			integer = Toggle "Integer" false;
57
58			_result
59				= fn sigma.value min_amplitude.value
60			{
61				fn
62					= im_log_imask, integer
63					= im_log_dmask;
64			}
65		}
66	}
67}
68
69#separator
70
71Matrix_extract_item = class
72	Menupullright "_Extract" "extract rows or columns from a matrix" {
73	extract n f = take (to_real n) @ drop (to_real f);
74
75	Rows_item = class
76		Menuaction "_Rows" "extract rows" {
77		action x = class
78			_result {
79			_vislevel = 3;
80
81			first = Expression "Extract from row" 0;
82			number = Expression "Extract this many rows" 1;
83
84			_result
85				= map_unary process x
86			{
87				process mat
88					= mat.Matrix_base (extract number first mat.value);
89			}
90		}
91	}
92
93	Columns_item = class
94		Menuaction "_Columns" "extract columns" {
95		action x = class
96			_result {
97			_vislevel = 3;
98
99			first = Expression "Extract from column" 0;
100			number = Expression "Extract this many columns" 1;
101
102			_result
103				= map_unary process x
104			{
105				process mat
106					= mat.Matrix_base (map (extract number first) mat.value);
107			}
108		}
109	}
110
111	Diagonal_item = class
112		Menuaction "_Diagonal" "extract diagonal" {
113		action x = class
114			_result {
115			_vislevel = 3;
116
117			which = Option "Extract" [
118				"Leading Diagonal",
119				"Trailing Diagonal"
120			] 0;
121
122			_result
123				= map_unary process x
124			{
125				process mat
126					= mat.Matrix_base (map2 (extract 1) [0..] mat.value),
127						which == 0
128					= mat.Matrix_base (map2 (extract 1)
129						[mat.width - 1, mat.width - 2 .. 0] mat.value);
130			}
131		}
132	}
133}
134
135Matrix_insert_item = class
136	Menupullright "_Insert" "insert rows or columns into a matrix" {
137	// insert a thing in a list at position first
138	insert first x l
139		= take first l ++ x ++ drop first l;
140
141	Rows_item = class
142		Menuaction "_Rows" "insert rows" {
143		action x = class
144			_result {
145			_vislevel = 3;
146
147			first = Expression "Insert at row" 0;
148			number = Expression "Insert this many rows" 1;
149			item = Expression "Set new cells to" 0;
150
151			_result
152				= map_unary process x
153			{
154				process mat
155					= mat.Matrix_base (insert (to_real first) rows mat.value)
156				{
157					row = replicate mat.width (to_real item);
158					rows = replicate (to_real number) row;
159				}
160			}
161		}
162	}
163
164	Columns_item = class
165		Menuaction "_Columns" "remove columns" {
166		action x = class
167			_result {
168			_vislevel = 3;
169
170			first = Expression "Insert at column" 0;
171			number = Expression "Insert this many columns" 1;
172			item = Expression "Set new cells to" 0;
173
174			_result
175				= map_unary process x
176			{
177				process mat
178					= mat.Matrix_base
179						(map (insert (to_real first) cells) mat.value)
180				{
181					cells = replicate (to_real number) (to_real item);
182				}
183			}
184		}
185	}
186}
187
188Matrix_delete_item = class
189	Menupullright "_Delete" "delete rows or columns from a matrix" {
190	// remove number of items, starting at first
191	delete first number l = take (to_real first) l ++
192		drop (to_real first + to_real number) l;
193
194	Rows_item = class
195		Menuaction "_Rows" "delete rows" {
196
197		action x = class
198			_result {
199			_vislevel = 3;
200
201			first = Expression "Delete from row" 0;
202			number = Expression "Delete this many rows" 1;
203
204			_result
205				= map_unary process x
206			{
207				process mat
208					= mat.Matrix_base (delete first number mat.value);
209			}
210		}
211
212	}
213
214	Columns_item = class
215		Menuaction "_Columns" "delete columns" {
216		action x = class
217			_result {
218			_vislevel = 3;
219
220			first = Expression "Delete from column" 0;
221			number = Expression "Delete this many columns" 1;
222
223			_result
224				= map_unary process x
225			{
226				process mat
227					= mat.Matrix_base (map (delete first number) mat.value);
228			}
229		}
230	}
231}
232
233Matrix_rotate_item = class
234	Menupullright "_Rotate" "clockwise rotation by fixed angles" {
235
236	rot90 = Image_transform_item.Rotate_item.Fixed_item.Rot90_item;
237
238	rot180 = Image_transform_item.Rotate_item.Fixed_item.Rot180_item;
239
240	rot270 = Image_transform_item.Rotate_item.Fixed_item.Rot270_item;
241
242	Matrix_rot45_item = class
243		Menuaction "_45 Degrees"
244			"45 degree rotate (square, odd-length-sides only)" {
245		action x = map_unary rot45 x;
246	}
247}
248
249Matrix_flip_item = Image_transform_item.Flip_item;
250
251#separator
252
253Matrix_invert_item = class
254	Menuaction "In_vert" "calculate inverse matrix" {
255	action x = map_unary (converse power (-1)) x;
256}
257
258Matrix_transpose_item = class
259	Menuaction "_Transpose" "swap rows and columns" {
260	action x = map_unary transpose x;
261}
262
263#separator
264
265Matrix_convert_to_image_item = class
266	Menuaction "Matrix to I_mage" "convert matrix to image" {
267	action x = class
268		_result {
269		_vislevel = 3;
270
271		conversion = Option "Convert to" [
272			"Monochrome image, same size as matrix",
273			"Multiband image, each row becomes a pixel"
274		] 0;
275
276		_result
277			= map_unary process x
278		{
279			process mat
280				= Image im, conversion == 0
281				= Image joinup
282			{
283				im = im_mask2vips mat;
284
285				joinup = bandjoin
286					(map extract_column
287						[0 .. mat.width - 1]);
288
289				extract_column n
290					= extract_area n 0 1 mat.height im;
291			}
292		}
293	}
294}
295
296Matrix_from_image_item = class
297	Menuaction "Image to M_atrix" "convert image to matrix" {
298	action x = map_unary to_matrix x;
299}
300
301#separator
302
303Matrix_plot_scatter_item = class
304	Menuaction "_Plot Scatter"
305		"plot a scatter graph of a matrix of [x,y] coordinates" {
306	action x = class
307		_result {
308		_check_args = [
309			[x, "x", check_Matrix_width 2]
310		];
311		_vislevel = 3;
312
313		gwidth = Expression "Graph size across (pixels)" 512;
314		gheight = Expression "Graph size down (pixels)" 512;
315		plot_colour = Colour_picker "Lab" [80, -80, 80];
316		xmin = Expression "X range minimum"
317			(foldr1 min_pair (map (extract 0) x.value));
318		xmax = Expression "X range maximum"
319			(foldr1 max_pair (map (extract 0) x.value));
320		ymin = Expression "Y range minimum"
321			(foldr1 min_pair (map (extract 1) x.value));
322		ymax = Expression "Y range maximum"
323			(foldr1 max_pair (map (extract 1) x.value));
324		axies = Toggle "Draw axies" true;
325
326		mark
327			= Mark this p?0 p?1
328		{
329			p = _to_image x.value?0;
330		}
331		mark_hint = "Mark is at position:";
332		mark_position = _from_image [mark.left, mark.top];
333
334		// geometry
335		_xrange = to_real xmax - to_real xmin;
336		_yrange = to_real ymax - to_real ymin;
337		_xscale = to_real gwidth / _xrange;
338		_yscale = to_real gheight / _yrange;
339
340		// map an [x,y] point into the image coordinates
341		_to_image p = [(p?0 - to_real xmin) * _xscale,
342			to_real gheight - (p?1 - to_real ymin) * _yscale];
343
344		// map an [x,y] point from image cods back to real cods
345		_from_image p = [p?0 / _xscale + to_real xmin,
346			(to_real gheight - p?1) / _yscale + to_real ymin];
347
348		_result
349			= Image (foldr plot background' x.value)
350		{
351			// colourspace we are drawing in
352			space = Image_type.colour_spaces.lookup
353				0 1 plot_colour.colour_space;
354
355			plot_image_new width height pixel
356				= image_new width height 3 Image_format.FLOAT
357					Image_coding.NOCODING space pixel 0 0;
358
359			// background
360			background = plot_image_new (to_real gwidth) (to_real gheight) 0;
361
362			// mark we plot
363			mark_width = max_pair 1 (to_real gwidth / 100);
364			mark_height = max_pair 1 (to_real gheight / 100);
365			mark = plot_image_new mark_width mark_height plot_colour;
366
367			// draw axies on background
368			background'
369				= drawxy, axies
370				= background
371			{
372				// colour we draw axies in
373				ax_col = colour_transform_to space (Colour "Lab" [100, 0, 0]);
374
375				// axies
376				xaxis = plot_image_new (to_real gwidth) 1 ax_col;
377				yaxis = plot_image_new 1 (to_real gheight) ax_col;
378				origin = _to_image [0, 0];
379
380				drawx = insert_noexpand 0 origin?1 xaxis background;
381				drawxy = insert_noexpand origin?0 0 yaxis drawx;
382			}
383
384			// plot a single point on an image
385			plot p im
386				= insert_noexpand
387					(x - mark_width / 2) (y - mark_height / 2) mark im
388			{
389				p' = _to_image p;
390				x = p'?0;
391				y = p'?1;
392			}
393		}
394	}
395}
396