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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
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()) {
int z = imp.getSlice();
int t = imp.getFrame();
ImagePlus[] channels = split(imp);
imp.changes = false;
imp.setIgnoreFlush(true);
imp.close();
for (int i=0; i<channels.length; i++) {
channels[i].setIJMenuBar(i==channels.length-1);
channels[i].show();
if (z>1 || t>1)
channels[i].setPosition(1, z, t);
}
} 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();
int pos = imp.getCurrentSlice();
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.setIJMenuBar(false);
rImp.show();
rImp.setSlice(pos);
if (IJ.isMacOSX()) IJ.wait(500);
ImagePlus gImp = new ImagePlus(title+" (green)", channels[1]);
gImp.setCalibration(cal);
gImp.setIJMenuBar(false);
gImp.show();
gImp.setSlice(pos);
if (IJ.isMacOSX()) IJ.wait(500);
ImagePlus bImp = new ImagePlus(title+" (blue)", channels[2]);
bImp.setCalibration(cal);
bImp.show();
bImp.setSlice(pos);
}
/** Splits the specified image into separate channels. */
public static ImagePlus[] split(ImagePlus imp) {
if (imp.getType()==ImagePlus.COLOR_RGB) {
ImageStack[] stacks = splitRGB(imp.getStack(), true);
ImagePlus[] images = new ImagePlus[3];
images[0] = new ImagePlus("red", stacks[0]);
images[1] = new ImagePlus("green", stacks[1]);
images[2] = new ImagePlus("blue", stacks[2]);
return images;
}
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()==IJ.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);
}
/** Returns, as an ImageStack, the specified channel, where 'c' must be greater
than zero and less than or equal to the number of channels in the image. */
public static ImageStack getChannel(ImagePlus imp, int c) {
if (imp.getBitDepth()==24) { // RGB?
if (c<1 || c>3)
throw new IllegalArgumentException("Channel must be 1,2 or 3");
ImageStack[] channels = splitRGB(imp.getStack(), true);
return channels[c-1];
}
if (c<1 || c>imp.getNChannels())
throw new IllegalArgumentException("Channel less than 1 or greater than "+imp.getNChannels());
ImageStack stack1 = imp.getStack();
ImageStack stack2 = new ImageStack(imp.getWidth(), imp.getHeight());
for (int t=1; t<=imp.getNFrames(); t++) {
for (int z=1; z<=imp.getNSlices(); z++) {
int n = imp.getStackIndex(c, z, t);
stack2.addSlice(stack1.getProcessor(n));
}
}
return stack2;
}
/** 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;
}
}
|