11 #ifndef STACK_PROCESS_HPP
12 #define STACK_PROCESS_HPP
35 setName(
"Stack/Mesh Interaction/Annihilate");
36 setDesc(
"Keep or fill a layer near the mesh");
37 setIcon(QIcon(
":/images/Annihilate.png"));
39 addParm(
"Fill",
"Fill the layer with specified value, or keep the original data.",
"No", booleanChoice());
40 addParm(
"Fill Val",
"Value to fill the volume with.",
"30000");
41 addParm(
"Min Dist(µm)",
"Minimal distance from layer to mesh.",
"1.0");
42 addParm(
"Max Dist(µm)",
"Maximal distance from layre to mesh",
"5.0");
47 if(!checkState().store(STORE_NON_EMPTY).mesh(MESH_NON_EMPTY))
49 Store* input = currentStack()->currentStore();
50 Store* output = currentStack()->work();
54 = run(input, output, currentMesh(), parm(
"Min Dist(µm)").toFloat(), parm(
"Max Dist(µm)").toFloat(),
55 fill, parm(
"Fill Val").toUInt());
71 bool run(
const Store* input,
Store* output,
const Mesh* mesh,
float minDist,
72 float maxDist,
bool fill,
uint fillval);
87 if(!checkState().store(STORE_NON_EMPTY))
89 Store* input = currentStack()->currentStore();
90 Store* output = currentStack()->work();
91 bool res = run(input, output);
115 setName(
"Stack/Filters/Apply Transfer Function");
116 setDesc(
"Apply the transfer function to the stack (modifies voxel values).");
117 setIcon(QIcon(
":/images/Palette.png"));
119 addParm(
"Red",
"Red",
"0");
120 addParm(
"Green",
"Green",
"0");
121 addParm(
"Blue",
"Blue",
"0");
122 addParm(
"Alpha",
"Alpha",
"1");
127 if(!checkState().store(STORE_NON_EMPTY))
129 Store* input = currentStack()->currentStore();
130 Store* output = currentStack()->work();
132 = run(input, output, parm(
"Red").toFloat(), parm(
"Green").toFloat(), parm(
"Blue").toFloat(),
133 parm(
"Alpha").toFloat());
152 bool run(
Store* store,
Store* output,
float red,
float green,
float blue,
float alpha);
165 setName(
"Stack/Segmentation/Blob Detect");
166 setDesc(
"Find and label blobs in an image");
167 setIcon(QIcon(
":/images/BlobDetect.png"));
169 addParm(
"Use watershed",
"Use watershed",
"No", booleanChoice());
170 addParm(
"Start Label",
"Start Label",
"1");
175 if(!checkState().store(STORE_NON_EMPTY | STORE_NON_LABEL))
178 Store* input = currentStack()->currentStore();
179 Store* output = currentStack()->work();
180 bool res = run(input, output, wat, parm(
"Start Label").toUInt());
187 bool run(
const Store* input,
Store* output,
bool watershed,
uint startlabel);
200 setName(
"Stack/System/Clear Work Stack");
201 setDesc(
"Clear the work stack");
202 setIcon(QIcon(
":/images/ClearStack.png"));
204 addParm(
"Fill value",
"Fill value",
"0");
210 if(!checkState().store(STORE_WORK))
212 return run(currentStack(), parm(
"Fill value").toUInt());
228 setName(
"Stack/System/Clear Main Stack");
229 setDesc(
"Clear the main stack");
230 setIcon(QIcon(
":/images/ClearStack.png"));
232 addParm(
"Fill value",
"Fill value",
"0");
238 if(!checkState().store(STORE_MAIN))
240 return run(currentStack(), parm(
"Fill value").toUInt());
256 setName(
"Stack/Canvas/Clip Stack");
257 setDesc(
"Trim stack to clipping planes");
258 setIcon(QIcon(
":/images/ClipStack.png"));
259 addParm(
"Trim canvas?",
"Use AutoTrim to reduce canvas size after clipping the stack.",
"No", booleanChoice());
264 if(!checkState().store(STORE_NON_EMPTY))
266 Store* input = currentStack()->currentStore();
267 Store* output = currentStack()->work();
268 bool res = run(input, output,
stringToBool(parm(
"Trim canvas?")));
276 bool run(
const Store* input,
Store* output,
bool trimStack);
289 setName(
"Stack/MultiStack/Copy Main to Work Stack");
290 setDesc(
"Copy Main to Work Stack");
291 setIcon(QIcon(
":/images/CopyMainToWork.png"));
296 if(!checkState().store(STORE_MAIN | STORE_NON_EMPTY))
298 Stack* stack = currentStack();
299 bool res = run(stack);
307 bool run(
Stack* stack);
320 setName(
"Stack/MultiStack/Copy Work to Main Stack");
321 setDesc(
"Copy Work to Main Stack");
322 setIcon(QIcon(
":/images/CopyWorkToMain.png"));
327 if(!checkState().store(STORE_WORK | STORE_NON_EMPTY))
329 Stack* stack = currentStack();
330 bool res = run(stack);
338 bool run(
Stack* stack);
351 setName(
"Stack/MultiStack/Swap or Copy Stack 1 and 2");
352 setDesc(
"Copy or Swap Stack 1 and 2");
353 setIcon(QIcon(
":/images/CopySwapStacks.png"));
355 addParm(
"Store",
"Store",
"Main", QStringList() <<
"Main" <<
"Work");
356 addParm(
"Action",
"Action",
"1 -> 2", QStringList() <<
"1 -> 2" <<
"1 <- 2" <<
"1 <-> 2");
362 bool res = run(parm(
"Store"), parm(
"Action"));
371 bool run(
const QString& storeStr,
const QString& actionStr);
384 setName(
"Stack/Mesh Interaction/Fill Stack from Mesh");
385 setDesc(
"Fill volume contained by closed mesh");
386 setIcon(QIcon(
":/images/TrimStack.png"));
388 addParm(
"Label",
"If >= 0 only this label is used",
"-1");
389 addParm(
"Fill Value",
"Fill Value",
"32000");
395 if(!checkState().store(STORE_NON_EMPTY).mesh(MESH_NON_EMPTY))
397 Store* input = currentStack()->currentStore();
398 Store* output = currentStack()->work();
399 Mesh* mesh = currentMesh();
402 fillValue = parm(
"Fill Value").toUInt();
403 bool res = run(input, output, mesh, parm(
"Label").toInt(), fill, fillValue);
412 int label,
bool fill,
uint fillValue);
426 setName(
"Stack/Mesh Interaction/Fill Stack from Mesh");
427 setDesc(
"Fill volume contained by closed mesh");
428 setIcon(QIcon(
":/images/TrimStack.png"));
430 addParm(
"Label",
"If >= 0 only this label is used",
"-1");
431 addParm(
"Fill Value",
"Fill Value",
"32000");
449 setName(
"Stack/Mesh Interaction/Trim Stack");
450 setDesc(
"Trim parts of stack which are not contained within closed mesh.");
451 setIcon(QIcon(
":/images/TrimStack.png"));
453 addParm(
"Label",
"If >= 0 only this label is used",
"-1");
471 setName(
"Stack/Mesh Interaction/Fill Stack from 3D Mesh");
472 setDesc(
"Fill stack contained by labeled 3D mesh");
473 setIcon(QIcon(
":/images/FillStack3D.png"));
478 if(!checkState().store(STORE_NON_EMPTY).mesh(MESH_NON_EMPTY))
480 Store* input = currentStack()->currentStore();
481 Store* output = currentStack()->work();
482 Mesh* mesh = currentMesh();
483 bool res = run(input, output, mesh);
506 setName(
"Stack/MultiStack/Swap Main and Work Stacks");
507 setDesc(
"Swap the main and work data of the current stack.");
508 setIcon(QIcon(
":/images/SwapStacks.png"));
513 if(!checkState().stack(STACK_NON_EMPTY))
515 Stack* s = currentStack();
517 setErrorMessage(
"You need to select a stack to launch this process.");
523 bool run(
Stack* stack);
536 setName(
"Stack/Canvas/Reverse Axes");
537 setDesc(
"Reverse the direction of the selected axes. Press A-key to display the axis.");
538 setIcon(QIcon(
":/images/Resize.png"));
540 addParm(
"X",
"X",
"No", QStringList() <<
"Yes" <<
"No");
541 addParm(
"Y",
"Y",
"No", QStringList() <<
"Yes" <<
"No");
542 addParm(
"Z",
"Z",
"Yes", QStringList() <<
"Yes" <<
"No");
547 if(!checkState().store(STORE_NON_EMPTY))
549 Stack* s = currentStack();
555 if(run(output, input, reverse_x, reverse_y, reverse_z)) {
563 bool run(
Store* output,
const Store* input,
bool x,
bool y,
bool z);
576 setName(
"Stack/Canvas/Change Voxel Size");
577 setDesc(
"Change the size of a voxel (i.e. doesn't change the data)");
578 setIcon(QIcon(
":/images/Resize.png"));
580 addParm(
"X (µm)",
"X (µm)",
"1.0");
581 addParm(
"Y (µm)",
"Y (µm)",
"1.0");
582 addParm(
"Z (µm)",
"Z (µm)",
"1.0");
587 if(!checkState().stack(STORE_NON_EMPTY))
589 Stack* s = currentStack();
590 Point3f nv(parm(
"X (µm)").toFloat(), parm(
"Y (µm)").toFloat(), parm(
"Z (µm)").toFloat());
607 setName(
"Stack/Canvas/Resize Canvas");
608 setDesc(
"Resize the stack to add or remove voxels.Make sure BBox is checked on before running.");
609 setIcon(QIcon(
":/images/Resize.png"));
611 addParm(
"Relative",
"If true, X, Y and Z are given in percentage, if false in voxels.",
"Yes", booleanChoice());
612 addParm(
"Center",
"New canvas centered as the old one, or else use the bottom left corner as reference.",
"Yes", booleanChoice());
613 addParm(
"X",
"Canvas size for X direction, in percentage or voxels.",
"0");
614 addParm(
"Y",
"Canvas size for Y direction, in percentage or voxels.",
"0");
615 addParm(
"Z",
"Canvas size for Z direction, in percentage or voxels.",
"0");
620 if(!checkState().stack(STORE_NON_EMPTY))
622 Stack* s = currentStack();
623 Point3i ds(parm(
"X").toInt(), parm(
"Y").toInt(), parm(
"Z").toInt());
627 bool run(
Stack* stack,
bool isRelative,
bool center,
Point3i ds);
640 setName(
"Stack/Canvas/Scale Stack");
641 setDesc(
"Scale the stack.");
642 setIcon(QIcon(
":/images/Scale.png"));
644 addParm(
"Percent",
"Percent",
"Yes", QStringList() <<
"Yes" <<
"No");
645 addParm(
"X",
"X",
"0.0");
646 addParm(
"Y",
"Y",
"0.0");
647 addParm(
"Z",
"Z",
"0.0");
652 if(!checkState().stack(STORE_NON_EMPTY))
654 Stack* s = currentStack();
655 Point3f newsize(parm(
"X").toFloat(), parm(
"Y").toFloat(), parm(
"Z").toFloat());
673 setName(
"Stack/Canvas/Shift Stack");
674 setDesc(
"Shift both stores of the stack to within the canvas.");
675 setIcon(QIcon(
":/images/Shift.png"));
677 addParm(
"Origin",
"Origin",
"No", booleanChoice());
678 addParm(
"X",
"X",
"0");
679 addParm(
"Y",
"Y",
"0");
680 addParm(
"Z",
"Z",
"0");
685 if(!checkState().store(STORE_NON_EMPTY))
687 Stack* s = currentStack();
688 Point3i ds(parm(
"X").toInt(), parm(
"Y").toInt(), parm(
"Z").toInt());
706 setName(
"Stack/Segmentation/Relabel");
707 setDesc(
"Relabel a 3D stack to use consecutive labels. The cells are shuffled so each relabling will be different.");
708 setIcon(QIcon(
":/images/Relabel.png"));
710 addParm(
"StartLabel",
"StartLabel",
"1");
711 addParm(
"Step",
"Step",
"1");
716 if(!checkState().store(STORE_NON_EMPTY | STORE_LABEL))
718 Stack* s = currentStack();
721 int start = parm(
"StartLabel").toInt();
722 int step = parm(
"Step").toInt();
723 if(run(s, store, output, start, step)) {
731 bool run(
Stack* stack,
const Store* store,
Store* output,
int start,
int step);
747 setName(
"Stack/Mesh Interaction/Relabel From Mesh");
748 setDesc(
"Relabel a 3D stack reusing the same labels as in the stack.\n"
749 "Unknown cells (i.e. cells in the stack, not in the mesh), \n"
750 "can be either kept or deleted. If kept, they will be relabeled\n"
751 "to not conflict with existing cells.");
752 setIcon(QIcon(
":/images/Relabel.png"));
754 addParm(
"Delete unknown",
"Delete unknown",
"Yes", booleanChoice());
759 if(!checkState().store(STORE_NON_EMPTY | STORE_LABEL).mesh(MESH_NON_EMPTY | MESH_LABEL))
761 Stack* s = currentStack();
764 const Mesh* m = currentMesh();
765 if(run(s, store, output, m,
stringToBool(parm(
"Delete unknown")))) {
774 bool delete_unknown);
788 setName(
"Stack/Mesh Interaction/Delete Outside Mesh");
789 setDesc(
"Delete labels outside a mesh of 3D cells based on a threshold distance from the centers.");
790 setIcon(QIcon(
":/images/Relabel.png"));
792 addParm(
"Threshold",
"Threshold Distance (um)",
"1");
797 Stack* stack = currentStack();
799 throw QString(
"%1::run No current stack").arg(name());
803 throw QString(
"%1::run No current store").arg(name());
806 throw QString(
"%1::run Store must be labeled").arg(name());
809 const Mesh* mesh = currentMesh();
811 throw QString(
"%1::run No current mesh").arg(name());
812 if(run(stack, input, output, mesh, parm(
"Threshold").toDouble())) {
820 bool run(
Stack* stack,
const Store* input,
Store* output,
const Mesh* mesh,
double threshold);
835 setName(
"Stack/Transform/Save Transform");
836 setDesc(
"Save the frame matrix (or transform if trans checked) to a file");
837 setIcon(QIcon(
":/images/save.png"));
839 addParm(
"Filename",
"Filename",
"");
842 bool initialize(QWidget* parent);
845 return run(currentStack(), parm(
"Filename"));
848 bool run(
Stack* stack,
const QString& filename);
864 setName(
"Stack/Transform/Load Transform");
865 setDesc(
"Save the frame matrix (or transform if trans checked) from a file");
866 setIcon(QIcon(
":/images/open.png"));
868 addParm(
"Filename",
"Filename",
"");
871 bool initialize(QWidget* parent);
874 return run(currentStack(), parm(
"Filename"));
877 bool run(
Stack* stack,
const QString& filename);
891 setName(
"Stack/Mesh Interaction/Distance Stack to Mesh");
892 setDesc(
"Fills the work stack with voxel values according to their distance to the current mesh");
893 setIcon(QIcon(
":/images/MeshDistance.png"));
895 addParm(
"Distance Multiplier",
"The distance in um is multiplied by this value and rounded to the nearest integer. \n"
896 "This is done to increase the range of the values and to provide a higher accuracy.",
"10.0");
903 Stack* s1 = currentStack();
906 Mesh* m = currentMesh();
907 return run(s1, store1, store2, m, parm(
"Distance Multiplier").toDouble());