diff --git a/examples/workflows/alexmac/config.json b/examples/workflows/alexmac/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..52a126c8c803052abfcec272f40f1a4194cbd290
--- /dev/null
+++ b/examples/workflows/alexmac/config.json
@@ -0,0 +1,27 @@
+{	
+        "version": "1.0",
+        "installdir": "/home/aknecht/stash/walia/ih/ih/build/scripts-2.7/",
+        "profile": {
+                "pegasus": {
+                        "style": "condor"
+                },
+                "condor": {
+                        "universe": "vanilla",
+			"requirements": "OSGVO_OS_STRING == \"RHEL 6\" && HAS_FILE_usr_lib64_libstdc___so_6 && CVMFS_oasis_opensciencegrid_org_REVISION >= 3590",
+                        "+WantsStashCache": "True"
+                }
+        },
+        "osg": {
+        	"tarball": "/home/aknecht/stash/walia/ih/ih/dist/ih-1.0.tar.gz",
+        	"ssh": "/home/aknecht/.ssh/workflow"
+	},
+        "cluster": 50,
+        "maxwalltime": {
+                "stats": 300,
+                "images": 3
+        },
+        "notify": {
+                "email": "avi@kurtknecht.com",
+                "pegasus_home": "/usr/share/pegasus/"
+        }
+}
diff --git a/examples/workflows/alexmac/crawl.json b/examples/workflows/alexmac/crawl.json
new file mode 100644
index 0000000000000000000000000000000000000000..635c0e464525080bbeb94f349e1edcf986b553c4
--- /dev/null
+++ b/examples/workflows/alexmac/crawl.json
@@ -0,0 +1,42 @@
+{
+	"path": "/home/aknecht/stash/9-22-15_lemnatec_images/alexmac/%experiment%_%id%-%genotype%_%date%_%null%_%null%/%stype%_%view%_%angle%/0_0_0.png",
+	"base": "/home/aknecht/stash/9-22-15_lemnatec_images/alexmac/",
+	"filetype": ".png",
+	"order": ["experiment", "id", "genotype", "date", "imgname", "imtype", "path"],
+	"translations": {
+		"imtype": {
+			"fluo_sv": "fluosv",
+			"vis_tv": "rgbtv",
+			"vis_sv": "rgbsv"
+		}
+	},
+	"data": {
+		"experiment": {
+			"type": "value",
+			"value": "%experiment%"
+		},
+		"id": {
+			"type": "value",
+			"value": "%id%"
+		},
+		"genotype": {
+			"type": "value",
+			"value": "%genotype%"
+		},
+		"date": {
+			"type": "date",
+			"value": "%date%",
+			"format": "Y-m-d"
+		},
+		"imtype": {
+			"type": "value",
+			"translate": "true",
+			"value": "%stype%_%view%",
+			"case": "lower"
+		},
+		"imgname": {
+			"type": "value",
+			"value": "%stype%_%view%_%angle%"
+		}
+	}
+}
diff --git a/examples/workflows/alexmac/fluosv_edge.json b/examples/workflows/alexmac/fluosv_edge.json
new file mode 100644
index 0000000000000000000000000000000000000000..03f1ef17653f8d73828ff7dfb161610b18ad1ab9
--- /dev/null
+++ b/examples/workflows/alexmac/fluosv_edge.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 590,
+    "yend": 1190,
+    "xstart": 219,
+    "xend": 799
+}
diff --git a/examples/workflows/alexmac/imgproc.json b/examples/workflows/alexmac/imgproc.json
new file mode 100644
index 0000000000000000000000000000000000000000..d73feb4e9a2bf1535609d838ab3dd5609b6d7aeb
--- /dev/null
+++ b/examples/workflows/alexmac/imgproc.json
@@ -0,0 +1,348 @@
+{
+	"workflows": {
+
+		"fluosv": [
+			{
+				"name": "gray",
+				"executable": "ih-convert-color",
+				"inputs": ["base"],
+				"outputs": ["grayscale"],
+				"arguments": {
+					"--intype": "bgr",
+					"--outtype": "gray"
+				}
+			},
+			{
+				"name": "blur",
+				"executable": "ih-gaussian-blur",
+				"inputs": ["grayscale"],
+				"outputs": ["blurred"],
+				"arguments": {
+					"--kwidth": 5,
+					"--kheight": 5
+				},
+				"depends": ["gray"]
+			},
+			{
+				"name": "thresh",
+				"executable": "ih-threshold",
+				"inputs": ["blurred"],
+				"outputs": ["masked"],
+				"arguments": {
+					"--thresh": 0,
+					"--max": 255,
+					"--type": "otsu"
+				},
+				"depends": ["blur"]
+			},
+			{
+				"name": "reconstitute",
+				"executable": "ih-bitwise-and",
+				"inputs": ["masked", "base"],
+				"outputs": ["recolor"],
+				"arguments": {},
+				"depends": ["thresh"]
+			},
+			{
+				"name": "crop",
+				"executable": "ih-crop",
+				"inputs": ["recolor", "/home/aknecht/stash/walia/ih/workflows/alexmac/input/fluosv_edge.json"],
+				"outputs": ["edged"],
+				"arguments": {},
+				"depends": ["reconstitute"]
+			},
+			{
+				"name": "cut",
+				"executable": "ih-contour-cut",
+				"inputs": ["edged", "edged"],
+				"outputs": ["final"],
+				"arguments": {
+					"--resize": "",
+					"--basemin": 50
+				},
+				"depends": ["crop"]
+			}
+		],
+
+
+
+		"rgbtv": [
+			{
+				"name": "blur",
+				"executable": "ih-gaussian-blur",
+				"inputs": ["base"],
+				"outputs": ["blurred"],
+				"arguments": {
+					"--kwidth": 13,
+					"--kheight": 13
+				}
+			},
+			{
+				"name": "sharpen",
+				"executable": "ih-add-weighted",
+				"inputs": ["base", "blurred"],
+				"outputs": ["sharpened"],
+				"arguments": {
+					"--weight1": 1.5,
+					"--weight2": -0.5
+				},
+				"depends": ["blur"]
+			},
+			{
+                                "name": "crop",
+                                "executable": "ih-crop",
+                                "inputs": ["sharpened", "/home/aknecht/stash/walia/ih/workflows/alexmac/input/rgbtv_edge.json"],
+                                "outputs": ["edged"],
+                                "arguments": {},
+                                "depends": ["sharpen"]
+                        },
+			{
+				"name": "cfilter1",
+				"executable": "ih-color-filter",
+				"inputs": ["edged"],
+				"outputs": ["cf1"],
+				"arguments": {
+					"--logic": "((r > b) or ((g > r) and ((g - b) > 10)))"
+				},
+				"depends": ["crop"]
+			},
+			{
+				"name": "bgr_lab",
+				"executable": "ih-convert-color",
+				"inputs": ["cf1"],
+				"outputs": ["lab_spectrum"],
+				"arguments": {
+					"--intype": "bgr",
+					"--outtype": "lab"
+				},
+				"depends": ["cfilter1"]
+			},
+			{
+				"name": "labfilter1",
+				"executable": "ih-color-filter",
+                                "inputs": ["lab_spectrum"],
+                                "outputs": ["lf1"],
+                                "arguments": {
+					"--logic": "((r - g) > 5)"
+                                },
+                                "depends": ["bgr_lab"]
+                        },
+			{
+				"name": "labfilter2",
+                                "executable": "ih-color-filter",
+                                "inputs": ["lf1"],
+                                "outputs": ["lf2"],
+                                "arguments": {
+					"--logic": "((r > b) and (g > b))"
+                                },
+                                "depends": ["labfilter1"]
+                        },
+			{
+				"name": "mask",
+				"executable": "ih-mask",
+				"inputs": ["lf2"],
+				"outputs": ["masked"],
+				"arguments": {},
+				"depends": ["labfilter2"]
+			},
+			{
+				"name": "reconstitute",
+				"executable": "ih-bitwise-and",
+				"inputs": ["masked", "base"],
+				"outputs": ["recolor"],
+				"arguments": {},
+				"depends": ["mask"]
+			},
+			{
+                                "name": "cfilter2",
+                                "executable": "ih-color-filter",
+                                "inputs": ["recolor"],
+                                "outputs": ["cf2"],
+                                "arguments": {
+					"--logic": "(((r - g) < ((i * i) / 4000)) or (((r - g) > (40 * (1 - (i / 765)))) and ((r - b) > (60 * (1 - (i / 765))))))"
+                                },
+                                "depends": ["reconstitute"]
+                        },
+			{
+				"name": "erode",
+				"executable": "ih-morphology",
+				"inputs": ["cf2"],
+				"outputs": ["morph_erode"],
+				"arguments": {
+					"--ktype": "ellipse",
+					"--kwidth": 3,
+					"--kheight": 3,
+					"--morphType": "erode"
+				},
+				"depends": ["cfilter2"]
+			},
+			{
+				"name": "contour_chop",
+				"executable": "ih-contour-chop",
+				"inputs": ["morph_erode", "morph_erode"],
+				"outputs": ["chop"],
+				"arguments": {
+					"--basemin": 100
+				},
+				"depends": ["erode"]
+			},
+			{
+                                "name": "mask2",
+                                "executable": "ih-mask",
+                                "inputs": ["chop"],
+                                "outputs": ["mask2"],
+                                "arguments": {},
+                                "depends": ["contour_chop"]
+                        },
+			{
+                                "name": "dilate",
+                                "executable": "ih-morphology",
+                                "inputs": ["mask2"],
+                                "outputs": ["morph_dilate"],
+                                "arguments": {
+                                        "--ktype": "ellipse",
+                                        "--kwidth": 3,
+                                        "--kheight": 3,
+                                        "--morphType": "dilate"
+                                },
+                                "depends": ["mask2"]
+                        },
+			{
+				"name": "reconstitute2",
+				"executable": "ih-bitwise-and",
+				"inputs": ["morph_dilate", "base"],
+				"outputs": ["recolor2"],
+				"arguments": {},
+				"depends": ["dilate"]
+			},
+			{
+				"name": "cut",
+				"executable": "ih-contour-cut",
+				"inputs": ["recolor2", "recolor2"],
+				"outputs": ["final"],
+				"arguments": {
+					"--basemin": 100,
+					"--resize": ""
+				},
+				"depends": ["reconstitute2"]
+			}
+		],
+		"rgbsv": [
+			{
+				"name": "gray",
+				"executable": "ih-convert-color",
+				"inputs": ["base"],
+				"outputs": ["grayscale"],
+				"arguments": {
+					"--intype": "bgr",
+					"--outtype": "gray"
+				}
+			},
+			{
+				"name": "blur",
+				"executable": "ih-gaussian-blur",
+				"inputs": ["grayscale"],
+				"outputs": ["blurred"],
+				"arguments": {
+					"--kwidth": 5,
+					"--kheight": 5
+				},
+				"depends": ["gray"]
+			},
+			{
+				"name": "thresh",
+				"executable": "ih-adaptive-threshold",
+				"inputs": ["blurred"],
+				"outputs": ["thresh"],
+				"arguments": {
+					"--value": 255,
+					"--thresholdType": "inverse",
+					"--adaptiveType": "mean",
+					"--blockSize": 15,
+					"--C": 6
+				},
+				"depends": ["blur"]
+			},
+			{
+				"name": "reconstitute",
+				"executable": "ih-bitwise-and",
+				"inputs": ["thresh", "base"],
+				"outputs": ["recolor"],
+				"arguments": {},
+				"depends": ["thresh"]
+			},
+			{
+				"name": "crop",
+				"executable": "ih-crop",
+				"inputs": ["recolor", "/home/aknecht/stash/walia/ih/workflows/alexmac/input/rgbsv_edge.json"],
+				"outputs": ["edged"],
+				"arguments": {},
+				"depends": ["reconstitute"]
+			},
+			{
+				"name": "fill",
+				"executable": "ih-fill",
+				"inputs": ["edged", "/home/aknecht/stash/walia/ih/workflows/alexmac/input/rgbsv_pot.json"],
+				"outputs": ["filled"],
+				"arguments": {},
+				"depends": ["crop"]
+			},
+			{
+				"name": "cut",
+				"executable": "ih-contour-cut",
+				"inputs": ["filled", "filled"],
+				"outputs": ["final"],
+				"arguments": {
+					"--basemin": 50,
+					"--resize": ""
+				},
+				"depends": ["fill"]
+			}
+		]
+	},
+	"options": {
+
+	},
+	"extract": {
+		"histogram-bin": {
+			"--group": {"rgb": ["rgbsv", "rgbtv"], "fluo": ["fluosv"]},
+			"--chunks": {"rgb": [5, 5, 5], "fluo": [0, 9, 10]},
+			"--channels": {"rgb": [0, 1, 2], "fluo": [1, 2]}
+		},
+		"workflows": {
+			"rgbsv": {
+				"inputs": ["final"],
+				"arguments": {
+					"--dimensions": "",
+					"--pixels": "",
+					"--moments": "",
+					"--circle": "",
+                    "--hull": ""
+				},
+				"depends": ["cut"]
+			},
+			"rgbtv": {
+				"inputs": ["final"],
+				"arguments": {
+					"--dimensions": "",
+					"--pixels": "",
+					"--moments": "",
+					"--circle": "",
+                    "--hull": ""
+				},
+				"depends": ["cut"]
+			},
+			"fluosv": {
+				"inputs": ["final"],
+				"arguments": {
+					"--dimensions": "",
+					"--pixels": "",
+					"--moments": "",
+					"--circle": "",
+					"--hull": ""
+				},
+				"depends": ["cut"]
+			}
+		}
+	}
+}
diff --git a/examples/workflows/alexmac/rgbsv_edge.json b/examples/workflows/alexmac/rgbsv_edge.json
new file mode 100644
index 0000000000000000000000000000000000000000..390309028720ceb22a242199335af50dc56bda75
--- /dev/null
+++ b/examples/workflows/alexmac/rgbsv_edge.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 400,
+    "yend": "y",
+    "xstart": 400,
+    "xend": "x - 400"
+}
diff --git a/examples/workflows/alexmac/rgbsv_pot.json b/examples/workflows/alexmac/rgbsv_pot.json
new file mode 100644
index 0000000000000000000000000000000000000000..1b72c0bd2de7f31ecd09d290388877fc187b5612
--- /dev/null
+++ b/examples/workflows/alexmac/rgbsv_pot.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 1746,
+    "yend": 2056,
+    "xstart": 992,
+    "xend": 1572
+}
diff --git a/examples/workflows/alexmac/rgbtv_edge.json b/examples/workflows/alexmac/rgbtv_edge.json
new file mode 100644
index 0000000000000000000000000000000000000000..04353d46377e23d1d874b7fa4b1a527ac0b959d4
--- /dev/null
+++ b/examples/workflows/alexmac/rgbtv_edge.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 350,
+    "yend": "y - 350",
+    "xstart": 350,
+    "xend": "x - 350"
+}
diff --git a/examples/workflows/blecha/config.json b/examples/workflows/blecha/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..52a126c8c803052abfcec272f40f1a4194cbd290
--- /dev/null
+++ b/examples/workflows/blecha/config.json
@@ -0,0 +1,27 @@
+{	
+        "version": "1.0",
+        "installdir": "/home/aknecht/stash/walia/ih/ih/build/scripts-2.7/",
+        "profile": {
+                "pegasus": {
+                        "style": "condor"
+                },
+                "condor": {
+                        "universe": "vanilla",
+			"requirements": "OSGVO_OS_STRING == \"RHEL 6\" &amp;&amp; HAS_FILE_usr_lib64_libstdc___so_6 &amp;&amp; CVMFS_oasis_opensciencegrid_org_REVISION >= 3590",
+                        "+WantsStashCache": "True"
+                }
+        },
+        "osg": {
+        	"tarball": "/home/aknecht/stash/walia/ih/ih/dist/ih-1.0.tar.gz",
+        	"ssh": "/home/aknecht/.ssh/workflow"
+	},
+        "cluster": 50,
+        "maxwalltime": {
+                "stats": 300,
+                "images": 3
+        },
+        "notify": {
+                "email": "avi@kurtknecht.com",
+                "pegasus_home": "/usr/share/pegasus/"
+        }
+}
diff --git a/examples/workflows/blecha/crawl.json b/examples/workflows/blecha/crawl.json
new file mode 100644
index 0000000000000000000000000000000000000000..dc5a4809add47f77cb84197a840823d564115092
--- /dev/null
+++ b/examples/workflows/blecha/crawl.json
@@ -0,0 +1,42 @@
+{
+	"path": "/home/aknecht/stash/9-22-15_lemnatec_images/Blecha 81315/%experiment%_%id%-%genotype%_%date%_%null%_%null%/%stype%_%view%_%angle%/0_0_0.png",
+	"base": "/home/aknecht/stash/9-22-15_lemnatec_images/Blecha 81315/",
+	"filetype": ".png",
+	"order": ["experiment", "id", "genotype", "date", "imgname", "imtype", "path"],
+	"translations": {
+		"imtype": {
+			"fluo_sv": "fluosv",
+			"vis_tv": "rgbtv",
+			"vis_sv": "rgbsv"
+		}
+	},
+	"data": {
+		"experiment": {
+			"type": "value",
+			"value": "%experiment%"
+		},
+		"id": {
+			"type": "value",
+			"value": "%id%"
+		},
+		"genotype": {
+			"type": "value",
+			"value": "%genotype%"
+		},
+		"date": {
+			"type": "date",
+			"value": "%date%",
+			"format": "Y-m-d"
+		},
+		"imtype": {
+			"type": "value",
+			"translate": "true",
+			"value": "%stype%_%view%",
+			"case": "lower"
+		},
+		"imgname": {
+			"type": "value",
+			"value": "%stype%_%view%_%angle%"
+		}
+	}
+}
diff --git a/examples/workflows/blecha/fluosv_edge.json b/examples/workflows/blecha/fluosv_edge.json
new file mode 100644
index 0000000000000000000000000000000000000000..03f1ef17653f8d73828ff7dfb161610b18ad1ab9
--- /dev/null
+++ b/examples/workflows/blecha/fluosv_edge.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 590,
+    "yend": 1190,
+    "xstart": 219,
+    "xend": 799
+}
diff --git a/examples/workflows/blecha/imgproc.json b/examples/workflows/blecha/imgproc.json
new file mode 100644
index 0000000000000000000000000000000000000000..4583089e0d7134a945e8f4f830954c0f5e8a703c
--- /dev/null
+++ b/examples/workflows/blecha/imgproc.json
@@ -0,0 +1,320 @@
+{
+	"workflows": {
+		"rgbtv": [
+			{
+				"name": "normalize",
+				"executable": "ih-normalize-intensity",
+				"inputs": ["base"],
+				"outputs": ["normal"],
+				"arguments": {}
+			},
+			{
+				"name": "crop_center",
+				"executable": "ih-crop",
+				"inputs": ["normal", "rgbtv_center.json"],
+				"outputs": ["centeronly"],
+				"arguments": {},
+				"depends": ["normalize"]
+			},
+			{
+				"name": "green_filter",
+				"executable": "ih-color-filter",
+				"inputs": ["centeronly"],
+				"outputs": ["gfilter"],
+				"arguments": {
+					"--logic": "(((g - r) > 15) and ((g - b) > 15))"
+				},
+				"depends": ["crop_center"]
+			},
+			{
+				"name": "create_seed_mask",
+				"executable": "ih-mask",
+				"inputs": ["gfilter"],
+				"outputs": ["seedmask"],
+				"arguments": {},
+				"depends": ["green_filter"]
+			},
+			{
+				"name": "blur",
+				"executable": "ih-blur",
+				"inputs": ["normal"],
+				"outputs": ["blurred"],
+				"arguments": {
+					"--kwidth": 3,
+					"--kheight": 3
+				},
+				"depends": ["normalize"]
+			},
+			{
+				"name": "sharpen",
+				"executable": "ih-add-weighted",
+				"inputs": ["normal", "blurred"],
+				"outputs": ["sharpened"],
+				"arguments": {
+					"--weight1": 1.5,
+					"--weight2": -0.5
+				},
+				"depends": ["blur"]
+			},
+			{
+				"name": "extract_green",
+				"executable": "ih-split",
+				"inputs": ["sharpened"],
+				"outputs": ["gchannel"],
+				"arguments": {
+					"--channel": 1
+				},
+				"depends": ["sharpen"]
+			},
+			{
+				"name": "equalize",
+				"executable": "ih-equalize-hist",
+				"inputs": ["gchannel"],
+				"outputs": ["equalized"],
+				"arguments": {},
+				"depends": ["extract_green"]
+			},
+			{
+				"name": "bg_cfilter",
+				"executable": "ih-color-filter",
+				"inputs": ["normal"],
+				"outputs": ["bg_noise"],
+				"arguments": {
+					"--logic": "(((high - low) < (i / 30)) or ((b - r) > (i / 10)))"
+				},
+				"depends": ["normalize"]
+			},
+			{
+				"name": "bgmask",
+				"executable": "ih-mask",
+				"inputs": ["bg_noise"],
+				"outputs": ["bg_mask"],
+				"arguments": {},
+				"depends": ["bg_cfilter"]
+			},
+			{
+				"name": "flood",
+				"executable": "ih-flood-fill",
+				"inputs": ["equalized", "bg_mask", "seedmask"],
+				"outputs": ["flooded"],
+				"arguments": {
+					"--low": "50",
+					"--high": "50",
+					"--writecolor": "255",
+					"--connectivity": 8,
+					"--findSeed": "",
+					"--binary": ""
+				},
+				"depends": ["equalize", "bgmask", "create_seed_mask"]
+			},
+			{
+				"name": "thresh",
+				"executable": "ih-threshold",
+				"inputs": ["flooded"],
+				"outputs": ["flood_binary"],
+				"arguments": {
+					"--thresh": 254,
+					"--type": "inverse"
+				},
+				"depends": ["flood"]
+			},
+			{
+				"name": "combine_with_mask",
+				"executable": "ih-bitwise-or",
+				"inputs": ["flood_binary", "bgmask"],
+				"outputs": ["invmask"],
+				"arguments": {},
+				"depends": ["thresh"]
+			},
+			{
+				"name": "invert",
+				"executable": "ih-bitwise-not",
+				"inputs": ["invmask"],
+				"outputs": ["premask"],
+				"arguments": {},
+				"depends": ["combine_with_mask"]
+			},
+			{
+				"name": "crop_edges",
+				"executable": "ih-crop",
+				"inputs": ["premask", "rgbtv_edge.json"],
+				"outputs": ["edged_mask"],
+				"depends": ["invert"]
+			},
+			{
+				"name": "chop",
+				"executable": "ih-contour-chop",
+				"inputs": ["edged_mask", "edged_mask"],
+				"outputs": ["chopped"],
+				"arguments": {
+					"--basemin": 50
+				},
+				"depends": ["crop_edges"]
+			},
+			{
+				"name": "erode",
+				"executable": "ih-morphology",
+				"inputs": ["chopped"],
+				"outputs": ["morph_erode"],
+				"arguments": {
+					"--ktype": "ellipse",
+					"--kwidth": 3,
+					"--kheight": 3,
+					"--morphType": "erode"
+				},
+				"depends": ["chop"]
+			},
+			{
+				"name": "dilate",
+				"executable": "ih-morphology",
+				"inputs": ["morph_erode"],
+				"outputs": ["morph_dilate"],
+				"arguments": {
+					"--ktype": "ellipse",
+					"--kwidth": 3,
+					"--kheight": 3,
+					"--morphType": "dilate"
+				},
+				"depends": ["erode"]
+			},
+			{
+				"name": "reconstitute",
+				"executable": "ih-bitwise-and",
+				"inputs": ["morph_dilate", "base"],
+				"outputs": ["recolor"],
+				"arguments": {},
+				"depends": ["dilate"]
+			},
+			{
+				"name": "cut",
+				"executable": "ih-contour-cut",
+				"inputs": ["recolor", "recolor"],
+				"outputs": ["final"],
+				"arguments": {
+					"--basemin": 50,
+					"--resize": ""
+				},
+				"depends": ["reconstitute"]
+			}
+		],
+		"rgbsv": [
+			{
+				"name": "normalize",
+				"executable": "ih-normalize-intensity",
+				"inputs": ["base"],
+				"outputs": ["normal"],
+				"arguments": {}
+			},
+			{
+				"name": "blur",
+				"executable": "ih-gaussian-blur",
+				"inputs": ["normal"],
+				"outputs": ["blurred"],
+				"arguments": {
+					"--kwidth": 5,
+					"--kheight": 5
+				},
+				"depends": ["normalize"]
+			},
+			{
+				"name": "gray_filter",
+				"executable": "ih-color-filter",
+				"inputs": ["blurred"],
+				"outputs": ["gfiltered"],
+				"arguments": {
+					"--logic": "((high - low) > (i / 30))"
+				},
+				"depends": ["blur"]
+			},
+			{
+				"name": "pot_filter",
+				"executable": "ih-color-filter",
+				"inputs": ["gfiltered"],
+				"outputs": ["pfiltered"],
+				"arguments": {
+					"--logic": "((g > b) and (g > r))"
+				},
+				"depends": ["gray_filter"]
+			},
+			{
+				"name": "box_filter",
+				"executable": "ih-color-filter",
+				"inputs": ["pfiltered"],
+				"outputs": ["bfiltered"],
+				"arguments": {
+					"--logic": "((g > b) and (g > r))"
+				},
+				"depends": ["pot_filter"]
+			},
+			{
+				"name": "crop",
+				"executable": "ih-crop",
+				"inputs": ["bfiltered", "rgbsv_edge.json"],
+				"outputs": ["edged"],
+				"arguments": {},
+				"depends": ["box_filter"]
+			},
+			{
+				"name": "mask",
+				"executable": "ih-mask",
+				"inputs": ["edged"],
+				"outputs": ["fmask"],
+				"arguments": {},
+				"depends": ["crop"]
+			},
+			{
+				"name": "reconstitute",
+				"executable": "ih-bitwise-and",
+				"inputs": ["fmask"],
+				"outputs": ["recolor"],
+				"arguments": {},
+				"depends": ["mask"]
+			},
+			{
+				"name": "cut",
+				"executable": "ih-contour-cut",
+				"inputs": ["recolor", "recolor"],
+				"outputs": ["final"],
+				"arguments": {
+					"--basemin": 50,
+					"--resize": ""
+				},
+				"depends": ["reconstitute"]
+			}
+		]
+	},
+	"options": {
+
+	},
+	"extract": {
+		"histogram-bin": {
+			"--group": {"rgb": ["rgbsv", "rgbtv"], "fluo": ["fluosv"]},
+			"--chunks": {"rgb": [5, 5, 5], "fluo": [0, 9, 10]},
+			"--channels": {"rgb": [0, 1, 2], "fluo": [1, 2]}
+		},
+		"workflows": {
+			"rgbsv": {
+				"inputs": ["final"],
+				"arguments": {
+					"--dimensions": "",
+					"--pixels": "",
+					"--moments": "",
+					"--circle": "",
+          "--hull": ""
+				},
+				"depends": ["cut"]
+			},
+			"rgbtv": {
+				"inputs": ["final"],
+				"arguments": {
+					"--dimensions": "",
+					"--pixels": "",
+					"--moments": "",
+					"--circle": "",
+          "--hull": ""
+				},
+				"depends": ["cut"]
+			}
+		}
+	}
+}
diff --git a/examples/workflows/blecha/rgbsv_box.json b/examples/workflows/blecha/rgbsv_box.json
new file mode 100644
index 0000000000000000000000000000000000000000..548ab9d4757764d89a00e2b37161d640ef44d010
--- /dev/null
+++ b/examples/workflows/blecha/rgbsv_box.json
@@ -0,0 +1,6 @@
+{
+  "ystart": 1931,
+  "yend": 2056,
+  "xstart": 1037,
+  "xstart": 1557
+}
diff --git a/examples/workflows/blecha/rgbsv_edge.json b/examples/workflows/blecha/rgbsv_edge.json
new file mode 100644
index 0000000000000000000000000000000000000000..8c64f5ddf595d88558864eac9370ef6a3962ce89
--- /dev/null
+++ b/examples/workflows/blecha/rgbsv_edge.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 1000,
+    "yend": "y",
+    "xstart": 400,
+    "xend": "x - 400"
+}
diff --git a/examples/workflows/blecha/rgbsv_pot.json b/examples/workflows/blecha/rgbsv_pot.json
new file mode 100644
index 0000000000000000000000000000000000000000..dbe7132b0e8c648c04b86bf8f6b84af65beb1ba5
--- /dev/null
+++ b/examples/workflows/blecha/rgbsv_pot.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 1806,
+    "yend": 2056,
+    "xstart": 1107,
+    "xend": 1487
+}
diff --git a/examples/workflows/blecha/rgbtv_center.json b/examples/workflows/blecha/rgbtv_center.json
new file mode 100644
index 0000000000000000000000000000000000000000..a76caaf02b93e9c25fdd24252ff7f95f41a5d148
--- /dev/null
+++ b/examples/workflows/blecha/rgbtv_center.json
@@ -0,0 +1,6 @@
+{
+  "ystart": 740,
+  "yend": 1350,
+  "xstart": 900,
+  "xend": 1520
+}
diff --git a/examples/workflows/blecha/rgbtv_edge.json b/examples/workflows/blecha/rgbtv_edge.json
new file mode 100644
index 0000000000000000000000000000000000000000..c48375dfd1867cccab4c689041eef534f8447671
--- /dev/null
+++ b/examples/workflows/blecha/rgbtv_edge.json
@@ -0,0 +1,6 @@
+{
+    "ystart": 200,
+    "yend": "y - 200",
+    "xstart": 200,
+    "xend": "x - 200"
+}
diff --git a/examples/workflows/blecha/stats.json b/examples/workflows/blecha/stats.json
new file mode 100644
index 0000000000000000000000000000000000000000..ee72e6a9b721f90e52bf37f6e2fb160cc48520e8
--- /dev/null
+++ b/examples/workflows/blecha/stats.json
@@ -0,0 +1,36 @@
+{
+	"rgb": [
+		{
+			"name": "area",
+			"executable": "pcv-stats-shoot-area",
+			"inputs": ["images"],
+			"outputs": ["shootarea"],
+			"arguments": {
+				"--group": {
+					"rgb": ["rgbsv"]
+				}
+			},
+			"depends": ["bin"]
+		},
+		{
+			"name": "normal",
+			"executable": "pcv-stats-normalize",
+			"inputs": ["shootarea"],
+			"outputs": ["normal"],
+			"arguments": {
+				"--column": "pixels"
+			},
+			"depends": ["area"]
+		},
+		{
+			"name": "threshold",
+			"executable": "pcv-stats-threshold",
+			"inputs": ["normal"],
+			"outputs": ["thresh"],
+			"arguments": {
+				"--thresh": 0.01
+			},
+			"depends": ["normal"]
+		}
+	]
+}
diff --git a/ih/conf.py b/ih/conf.py
index 01db04df782ba715f5a25512a7f4e8b2b72a0f7c..fb7da9c7703fec977addea51ea7ea437d9efab02 100644
--- a/ih/conf.py
+++ b/ih/conf.py
@@ -73,6 +73,7 @@ adaptives = {
     "gaussian": cv2.ADAPTIVE_THRESH_GAUSSIAN_C
 }
 
+
 """
 A dictionary used to map border-types to cv2 border codes
 """
@@ -617,6 +618,136 @@ valid = {
             }
         }
     },
+    "ih-split": {
+        "type": "imgproc",
+        "inputs": ["image"],
+        "outputs": ["image"],
+        "arguments": {
+           "--input": {
+                "type": "derived",
+                "key": "inputs",
+                "index": 0,
+                "required": "true"
+            },
+            "--output": {
+                "type": "derived",
+                "key": "outputs",
+                "index": 0,
+                "required": "true"
+            },
+            "--outputdir": {
+                "type": "overwrite",
+                "value": "."
+            },
+            "--writeblank": {
+                "type": "overwrite",
+                "required": "true",
+                "value": ""
+            },
+            "--channel": {
+                "type": "numeric",
+                "validation": "list",
+                "value": [0, 1, 2],
+                "required": "true"
+            }
+        }
+    },
+    "ih-equalize-hist": {
+        "type": "imgproc",
+        "inputs": ["image"],
+        "outputs": ["image"],
+        "arguments": {
+           "--input": {
+                "type": "derived",
+                "key": "inputs",
+                "index": 0,
+                "required": "true"
+            },
+            "--output": {
+                "type": "derived",
+                "key": "outputs",
+                "index": 0,
+                "required": "true"
+            },
+            "--outputdir": {
+                "type": "overwrite",
+                "value": "."
+            },
+            "--writeblank": {
+                "type": "overwrite",
+                "required": "true",
+                "value": ""
+            }
+        }
+    },
+    "ih-flood-fill": {
+        "type": "imgproc",
+        "inputs": ["image", "image", "image"],
+        "outputs": ["image"],
+        "arguments": {
+           "--input": {
+                "type": "derived",
+                "key": "inputs",
+                "index": 0,
+                "required": "true"
+            },
+            "--mask": {
+                "type": "derived",
+                "key": "inputs",
+                "index": 1,
+                "required": "true"
+            },
+            "--seedMask": {
+                "type": "derived",
+                "key": "inputs",
+                "index": 2
+            },
+            "--output": {
+                "type": "derived",
+                "key": "outputs",
+                "index": 0,
+                "required": "true"
+            },
+            "--outputdir": {
+                "type": "overwrite",
+                "value": "."
+            },
+            "--writeblank": {
+                "type": "overwrite",
+                "required": "true",
+                "value": ""
+            },
+            "--low": {
+                "type": "string",
+                "required": "true"
+            },
+            "--high": {
+                "type": "string",
+                "required": "true"
+            },
+            "--writeColor": {
+                "type": "string",
+                "required": "true"
+            },
+            "--connectivity": {
+                "type": "numeric",
+                "validation": "list",
+                "value": [4, 8]
+            },
+            "--fixed": {
+                "type": "exist"
+            },
+            "--seedx": {
+                "type": "numeric"
+            },
+            "--seedy": {
+                "type": "numeric"
+            },
+            "--findSeed": {
+                "type": "exist"
+            }
+        }
+    },
     "ih-fill": {
         "type": "imgproc",
         "inputs": ["image", "roi"],
diff --git a/ih/imgproc.py b/ih/imgproc.py
index d6c96d8c9f7b1e07afe1639d7a7a3f6d6bf122b9..3d2d7e7f57a4d41b4b349d1b265159d822f0f721 100644
--- a/ih/imgproc.py
+++ b/ih/imgproc.py
@@ -421,6 +421,16 @@ class Image(object):
         self.destroy()
         return
 
+    def split(self, channel):
+        self.image = cv2.split(self.image)[channel]
+        return
+
+    def equalizeHist(self):
+        if self._isColor():
+            self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
+        self.image = cv2.equalizeHist(self.image)
+        return
+
     def show(self, title = None, state = None):
         """
             :param title: The title to give the display window, if left blank one will be created.
@@ -821,6 +831,76 @@ class Image(object):
         else:
             raise Exception("Invalid morphology type, should be one of: " + ",".join(conf.morph.keys()) + ".")
 
+    def _findSeed(self, seedMask):
+        bname, binary = self._loadResource(seedMask)
+        if self._isColor(binary):
+            binary = cv2.cvtColor(binary, cv2.COLOR_BGR2GRAY)
+        contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, 2)
+        size = 0
+        select = 0
+        for cnt in contours:
+            if cv2.contourArea(cnt) > size:
+                select = cnt
+                size = cv2.contourArea(cnt)
+        return tuple(select[0][0])
+
+    def floodFill(self, mask, low, high, writeColor = (255, 255, 255), connectivity = 4, fixed = False, seed = (0,0), findSeed = False, seedMask = None, binary = False):
+        """
+        :param mask: A binary image corresponding to the area you don't want to fill.
+        :type mask: str or np.ndarray
+        :param seed: The beginning point to use for filling.
+        :type seed: Tuple (x, y)
+        :param low: Maximal lower brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component.
+        :type low: Tuple (b, g, r) or (i,)
+        :param high: Maximal upper brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component.
+        :type high: Tuple (b, g, r) or (i,)
+        :param writeColor: The color to write to the filled region.  Default (255, 255, 255).
+        :type writeColor: tuple (b, g, r) or (i,)
+        :param connectivity: The number of neighboring pixels to consider for the flooding operation.  Should be 4 or 8.
+        :type connectivity: int
+        :param fixed: If True, calculates color differences relative to the seed.
+        :type fixed: boolean
+        :param findSeed: If True, picks a seed point based on contours in the seedMask image.
+        :type findSeed: boolean
+        :param seedMask: Binary image to select seed from.
+        :type seedMask: str or np.ndarray
+        :param binary: Specify if input image is binary.
+        :type binary: boolean
+
+        This function is a wrapper to the OpenCV function `floodFill <http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html#floodfill>`_.
+        This function floods the region of an image based on calculated color differences from neighbors or from the seed.  When flooding a binary
+        image all input color tuples should have 1 value instead of 3.
+        """
+        print low,high,writeColor
+        mname, mask = self._loadResource(mask)
+        if self._isColor(mask):
+            mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
+        if binary and self._isColor():
+            self.convertColor("bgr", "gray")
+        # Mask is required to be 2 pixels wider and taller than the image
+        adjmask = np.zeros((self.y + 2, self.x + 2), np.uint8)
+        adjmask[1:1+self.y, 1:1+self.x] = mask
+        channels = 3 if len(self.image.shape) == 3 else 1
+        if len(low) == channels:
+            if len(high) == channels:
+                if len(writeColor) == channels:
+                    if connectivity == 4 or connectivity == 8:
+                        if findSeed and seedMask:
+                            seed = self._findSeed(seedMask)
+                        if fixed:
+                            cv2.floodFill(self.image, adjmask, seed, writeColor, low, high, connectivity | cv2.FLOODFILL_FIXED_RANGE)
+                        else:
+                            cv2.floodFill(self.image, adjmask, seed, writeColor, low, high, connectivity)
+                    else:
+                        raise Exception("Invalid value for connectivity, should be either 4 or 8.")
+                else:
+                    raise Exception("Incorrect number of values for write color.  Number of values should match input image channels (%s)" % (channels,))
+            else:
+                raise Exception("Incorrect number of values for high difference.  Number of values should match input image channels (%s)" % (channels,))
+        else:
+            raise Exception("Incorrect number of values for low difference.  Number of values should match input image channels (%s)" % (channels,))
+        return
+
     def fill(self, roi, color):
         """
         :param roi: A list corresponding to the area of the image you want.  List should be of the form [ystart, yend, xstart, xend]
diff --git a/scripts/ih-equalize-hist b/scripts/ih-equalize-hist
new file mode 100644
index 0000000000000000000000000000000000000000..2bc81e61e49f66e1b6286b30b3e70d93ae06e208
--- /dev/null
+++ b/scripts/ih-equalize-hist
@@ -0,0 +1,21 @@
+#!python
+import argparse
+import traceback
+import ih.imgproc
+
+parser = argparse.ArgumentParser(description = "Stretches a grayscale image to the full 0-255 intensity range.")
+parser.add_argument("--input", dest="input", help="Path to input image.", required = True)
+parser.add_argument("--outputdir", dest="outputdir", default=".", help="Path to write output files, if not specified use current directory.")
+parser.add_argument("--output", default=None, dest="output", help="Name of output image to write, if not specified, use input image name.")
+parser.add_argument("--writeblank", default=False, action="store_true", help="If errors happen, write a blank file.  Used to ensure dependent files exist for pegasus workflows.")
+args = parser.parse_args()
+
+try:
+    plant = ih.imgproc.Image(args.input, args.outputdir, args.output, False)
+    plant.equalizeHist()
+    plant.write()
+except Exception as e:
+    print traceback.format_exc()
+    if args.writeblank:
+        with open(args.outputdir + "/" + args.output, "w") as wh:
+            wh.write("not an image.")
diff --git a/scripts/ih-flood-fill b/scripts/ih-flood-fill
new file mode 100644
index 0000000000000000000000000000000000000000..ea4471589cc04d6929091ac3fc92ec3a88513a85
--- /dev/null
+++ b/scripts/ih-flood-fill
@@ -0,0 +1,42 @@
+#!python
+import argparse
+import traceback
+import ih.imgproc
+
+parser = argparse.ArgumentParser(description = "Smoothes an image based on a evenly distributed kernel.")
+parser.add_argument("--input", dest="input", help="Path to input image.", required = True)
+parser.add_argument("--mask", dest="mask", help="Path to mask image.", required = True)
+parser.add_argument("--low", dest="low", nargs="+", type=int, help="Maximal lower brigthness/color difference.", required = True)
+parser.add_argument("--high", dest="high", nargs="+", type=int, help="Maximal upper brigthness/color difference.", required = True)
+parser.add_argument("--writeColor", dest="writeColor", nargs="+", type=int, help="Write Color.")
+parser.add_argument("--connectivity", dest="connectivity", type=int, default=4, help="Number of neighboring pixels to consider.")
+parser.add_argument("--fixed", dest="fixed", default=False, action="store_true", help="Use difference relative to the seed.")
+parser.add_argument("--seedx", dest="seedx", type=int, default=0, help="X coordinate of the seed.")
+parser.add_argument("--seedy", dest="seedy", type=int, default=0, help="Y coordinate of the seed.")
+parser.add_argument("--findSeed", dest="findSeed", default=False, action="store_true", help="Calculate seed from a given image.")
+parser.add_argument("--seedMask", dest="seedMask", help="Path to seed mask image.")
+parser.add_argument("--binary", dest="binary", default=False, action="store_true", help="Specify if flood is performed on a grayscale image.")
+parser.add_argument("--outputdir", dest="outputdir", default=".", help="Path to write output files, if not specified use current directory.")
+parser.add_argument("--output", default=None, dest="output", help="Name of output image to write, if not specified, use input image name.")
+parser.add_argument("--writeblank", default=False, action="store_true", help="If errors happen, write a blank file.  Used to ensure dependent files exist for pegasus workflows.")
+args = parser.parse_args()
+
+try:
+    plant = ih.imgproc.Image(args.input, args.outputdir, args.output, False)
+    plant.floodFill(args.mask,
+                    tuple(args.low),
+                    tuple(args.high),
+                    writeColor = tuple(args.writeColor),
+                    connectivity = args.connectivity,
+                    fixed = args.fixed,
+                    seed = tuple([args.seedx, args.seedy]),
+                    findSeed = args.findSeed,
+                    seedMask = args.seedMask,
+                    binary = args.binary
+                    )
+    plant.write()
+except Exception as e:
+    print traceback.format_exc()
+    if args.writeblank:
+        with open(args.outputdir + "/" + args.output, "w") as wh:
+            wh.write("not an image.")
diff --git a/scripts/ih-split b/scripts/ih-split
new file mode 100644
index 0000000000000000000000000000000000000000..6b12d0e475c3a4074fcfa748fce6687cd6a8f3d9
--- /dev/null
+++ b/scripts/ih-split
@@ -0,0 +1,22 @@
+#!python
+import argparse
+import traceback
+import ih.imgproc
+
+parser = argparse.ArgumentParser(description = "Splits an image into channels and extracts a single one.")
+parser.add_argument("--input", dest="input", help="Path to input image.", required = True)
+parser.add_argument("--channel", dest="channel", type=int, help="Channel to extract.", required = True)
+parser.add_argument("--outputdir", dest="outputdir", default=".", help="Path to write output files, if not specified use current directory.")
+parser.add_argument("--output", default=None, dest="output", help="Name of output image to write, if not specified, use input image name.")
+parser.add_argument("--writeblank", default=False, action="store_true", help="If errors happen, write a blank file.  Used to ensure dependent files exist for pegasus workflows.")
+args = parser.parse_args()
+
+try:
+    plant = ih.imgproc.Image(args.input, args.outputdir, args.output, False)
+    plant.split(args.channel)
+    plant.write()
+except Exception as e:
+    print traceback.format_exc()
+    if args.writeblank:
+        with open(args.outputdir + "/" + args.output, "w") as wh:
+            wh.write("not an image.")
diff --git a/setup.py b/setup.py
index f3fe22ed674e6ceb686504c9ddb9e41ea088e132..7058356d589b682d424dd16ef39e94408cdd0533 100755
--- a/setup.py
+++ b/setup.py
@@ -29,6 +29,9 @@ setup(
 		"scripts/ih-resize",
         "scripts/ih-mask",
 		"scripts/ih-add-weighted",
+		"scripts/ih-split",
+		"scripts/ih-equalize-hist",
+		"scripts/ih-flood-fill",
 
 		"scripts/ih-setup",
 		"scripts/ih-crawl",