File: ChannelSplitter.java

package info (click to toggle)
imagej 1.46a-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,248 kB
  • sloc: java: 89,778; sh: 311; xml: 51; makefile: 6
file content (112 lines) | stat: -rw-r--r-- 3,536 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.measure.Calibration;
import ij.plugin.HyperStackReducer;
import java.awt.*;
import java.util.Vector;

/** This plugin implements the Image/Color/Split Channels command. */
public class ChannelSplitter implements PlugIn {

	public void run(String arg) {
		ImagePlus imp = IJ.getImage();
		if (imp.isComposite()) {
			ImagePlus[] channels = split(imp);
			for (int i=0; i<channels.length; i++)
				channels[i].show();
			imp.changes = false;
			imp.close();
		} else if (imp.getType()==ImagePlus.COLOR_RGB)
			splitRGB(imp);
		else 
			IJ.error("Split Channels", "Multichannel image required");
	}
	
	private void splitRGB(ImagePlus imp) {
		boolean keepSource = IJ.altKeyDown();
		String title = imp.getTitle();
		Calibration cal = imp.getCalibration();
		ImageStack[] channels = splitRGB(imp.getStack(), keepSource);
		if (!keepSource)
			{imp.unlock(); imp.changes=false; imp.close();}
		ImagePlus rImp = new ImagePlus(title+" (red)", channels[0]);
		rImp.setCalibration(cal);
		rImp.show();
		if (IJ.isMacOSX()) IJ.wait(500);
		ImagePlus gImp = new ImagePlus(title+" (green)", channels[1]);
		gImp.setCalibration(cal);
		gImp.show();
		if (IJ.isMacOSX()) IJ.wait(500);
		ImagePlus bImp = new ImagePlus(title+" (blue)", channels[2]);
		bImp.setCalibration(cal);
		bImp.show();
	}

	/** Splits the specified image into separate channels. */
	public static ImagePlus[] split(ImagePlus imp) {
		if (imp.getType()==ImagePlus.COLOR_RGB) {
			return null;
		}
		int width = imp.getWidth();
		int height = imp.getHeight();
		int channels = imp.getNChannels();
		int slices = imp.getNSlices();
		int frames = imp.getNFrames();
		int bitDepth = imp.getBitDepth();
		int size = slices*frames;
		Vector images = new Vector();
		HyperStackReducer reducer = new HyperStackReducer(imp);
		for (int c=1; c<=channels; c++) {
			ImageStack stack2 = new ImageStack(width, height, size); // create empty stack
			stack2.setPixels(imp.getProcessor().getPixels(), 1); // can't create ImagePlus will null 1st image
			ImagePlus imp2 = new ImagePlus("C"+c+"-"+imp.getTitle(), stack2);
			stack2.setPixels(null, 1);
			imp.setPosition(c, 1, 1);
			imp2.setDimensions(1, slices, frames);
			imp2.setCalibration(imp.getCalibration());
			reducer.reduce(imp2);
			if (imp.isComposite() && ((CompositeImage)imp).getMode()==CompositeImage.GRAYSCALE)
				IJ.run(imp2, "Grays", "");
			if (imp2.getNDimensions()>3)
				imp2.setOpenAsHyperStack(true);
			images.add(imp2);
		}
		ImagePlus[] array = new ImagePlus[images.size()];
		return (ImagePlus[])images.toArray(array);
	}
	
	/** Splits the specified RGB stack into three 8-bit grayscale stacks. 
		Deletes the source stack if keepSource is false. */
	public static ImageStack[] splitRGB(ImageStack rgb, boolean keepSource) {
		 int w = rgb.getWidth();
		 int h = rgb.getHeight();
		 ImageStack[] channels = new ImageStack[3];
		 for (int i=0; i<3; i++)
		 	channels[i] = new ImageStack(w,h);
		 byte[] r,g,b;
		 ColorProcessor cp;
		 int slice = 1;
		 int inc = keepSource?1:0;
		 int n = rgb.getSize();
		 for (int i=1; i<=n; i++) {
			 IJ.showStatus(i+"/"+n);
			 r = new byte[w*h];
			 g = new byte[w*h];
			 b = new byte[w*h];
			 cp = (ColorProcessor)rgb.getProcessor(slice);
			 slice += inc;
			 cp.getRGB(r,g,b);
			 if (!keepSource)
				rgb.deleteSlice(1);
			 channels[0].addSlice(null,r);
			 channels[1].addSlice(null,g);
			 channels[2].addSlice(null,b);
			 IJ.showProgress((double)i/n);
		}
		return channels;
	}

}