public void run(ImageProcessor ip) {

    dimz = stack.getSize();
    dimy = stack.getWidth();
    dimx = stack.getHeight();

    SaveDialog sd = new SaveDialog("Save Measurements as Text...", "res", ".dat");
    String name = sd.getFileName();
    if (name == null) return;

    String directory = sd.getDirectory();

    nb = calculnb(stack); // -1;
    IJ.showStatus("Measure parameters for the " + nb + " objects ...");
    if (nb < 1) {
      IJ.showMessage("volume must be labeled");
    } else {
      double[] volume_m = new double[nb];
      int[] volume_p = new int[nb];
      double[] surface = new double[nb];
      double[] surfacenb = new double[nb];
      double[][][] I = new double[3][3][nb];
      double[][] J = new double[3][nb];
      double[][][] dir = new double[3][3][nb];
      double[] xg = new double[nb];
      double[] yg = new double[nb];
      double[] zg = new double[nb];
      byte[] bord = new byte[nb];
      //       		double[] a = new double[nb];
      //       		double[] b = new double[nb];
      //       		double[] c = new double[nb];
      //       		double[] Fab = new double[nb];
      //       		double[] Fac = new double[nb];
      //       		double[] Fbc = new double[nb];
      //       		double[] sp = new double[nb];
      double[][] lmin = new double[nb][3];
      double[][] lmax = new double[nb][3];
      IJ.showStatus("Measure surfaces ...");
      calculmarchsurfstack(stack, nb, surface, volume_m);
      calculmarchsurfstacknb(stack, nb, surfacenb);
      // calculvolumestack(stack,nb,volume_p);
      IJ.showStatus("Measure volumes and inertia ...");
      calculcgstack(stack, nb, volume_p, xg, yg, zg);
      calculinertiestack(stack, nb, xg, yg, zg, I);
      inertie(nb, I, J, dir);
      IJ.showStatus("Measure bounding boxes ...");
      boitestack(stack, nb, xg, yg, zg, dir, lmin, lmax);
      borderstack(stack, nb, bord);
      IJ.showStatus("Save results ...");
      sauvegarde(
          volume_p, volume_m, surface, surfacenb, xg, yg, zg, J, dir, nb, bord, lmin, lmax,
          directory, name);
      volume_m = null;
      volume_p = null;
      surface = null;
      xg = null;
      yg = null;
      zg = null;
    }
  }
Пример #2
0
 void setStackDisplayRange(ImagePlus imp) {
   ImageStack stack = imp.getStack();
   double min = Double.MAX_VALUE;
   double max = -Double.MAX_VALUE;
   int n = stack.getSize();
   for (int i = 1; i <= n; i++) {
     if (!silentMode) IJ.showStatus("Calculating stack min and max: " + i + "/" + n);
     ImageProcessor ip = stack.getProcessor(i);
     ip.resetMinAndMax();
     if (ip.getMin() < min) min = ip.getMin();
     if (ip.getMax() > max) max = ip.getMax();
   }
   imp.getProcessor().setMinAndMax(min, max);
   imp.updateAndDraw();
 }
  void borderstack(final ImageStack stack1, int nb, byte[] b) {
    final AtomicInteger ai = new AtomicInteger(0);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final byte[][] bord = new byte[dimZ][nb];

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi < dimZ;
                  superi = ai.getAndIncrement()) {
                int k = superi;
                ImageProcessor ip = stack1.getProcessor(k + 1);
                for (int j = 0; j < dimY; j++) {
                  for (int i = 0; i < dimX; i++) {
                    int val = (int) (ip.getPixelValue(i, j));
                    if ((val != 0)
                        && (i == 0
                            || j == 0
                            || k == 0
                            || i == dimX - 1
                            || j == dimY - 1
                            || k == dimZ - 1))
                      // bord[k][val-2]=1;
                      bord[k][val - 1] = 1;
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);
    for (int i = 0; i < dimZ; i++) {
      for (int j = 0; j < nb; j++) {
        b[j] *= (1 - bord[i][j]);
      }
    }
    for (int j = 0; j < nb; j++) {
      b[j] = (byte) (1 - b[j]);
    }
  }
Пример #4
0
  public void showRois3D() {
    registerActiveImage();
    if (currentImage == null) return;
    // verifier que l'image active a les memes dimentions
    Object[] os = this.list.getSelectedValues();

    if (os.length == 1) {
      mcib3d.geom.Object3D o = ((Object3DGui) os[0]).getObject3D();
      currentImage.setSlice((o.getZmax() + o.getZmin()) / 2 + 1);
    }
    int nSlices = currentImage.getNSlices();

    currentROIs = new HashMap<Integer, Roi>(nSlices);
    // stores the roi mask to save memory..
    if (roiMask == null || !roiMask.sameDimentions(currentImage)) {
      roiMask = new ImageByte("mask", currentImage.getWidth(), currentImage.getHeight(), nSlices);
    } else {
      roiMask.erase();
    }
    ImageStack maskStack = roiMask.getImageStack();
    Object3DGui obj;
    for (Object o : os) {
      obj = (Object3DGui) o;
      obj.getObject3D().draw(maskStack, 255);
    }
    // roiMask.show();

    for (int i = 1; i <= nSlices; i++) {
      ImagePlus im = new ImagePlus("mask", maskStack.getProcessor(i));
      im.getProcessor().setThreshold(1, 255, ImageProcessor.NO_LUT_UPDATE);
      ThresholdToSelection tts = new ThresholdToSelection();
      tts.setup("", im);
      tts.run(im.getProcessor());
      Roi r = im.getRoi();
      if (r != null) currentROIs.put(i, r);
    }
    updateRoi();
  }
  public int calculnb(final ImageStack stack1) {
    final AtomicInteger ai = new AtomicInteger(1);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final int[] value = new int[dimZ];

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi <= dimZ;
                  superi = ai.getAndIncrement()) {
                int current = superi;
                ImageProcessor ip = stack1.getProcessor(current);
                for (int j = 0; j < dimY; j++) {
                  for (int i = 0; i < dimX; i++) {
                    int val = (int) (ip.getPixelValue(i, j));
                    if (val > value[current - 1]) value[current - 1] = val;
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);

    int val = 0;
    for (int i = 0; i < dimZ; i++) {
      if (val < value[i]) val = value[i];
    }
    return val;
  }
  void calculvolumestack(final ImageStack stack1, int nb, int v[]) {
    final AtomicInteger ai = new AtomicInteger(1);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final int[][] vol = new int[dimZ][nb];

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi <= dimZ;
                  superi = ai.getAndIncrement()) {
                int current = superi;
                ImageProcessor ip = stack1.getProcessor(current);
                for (int j = 0; j < dimY; j++) {
                  for (int i = 0; i < dimX; i++) {
                    int val = (int) (ip.getPixelValue(i, j));
                    // if (val!=0) vol[current-1][val-2]++;
                    if (val != 0) vol[current - 1][val - 1]++;
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);
    for (int i = 0; i < dimZ; i++) {
      for (int j = 0; j < nb; j++) {
        v[j] += vol[i][j];
      }
    }
  }
Пример #7
0
 /** Opens a stack of images. */
 ImagePlus openStack(ColorModel cm, boolean show) {
   ImageStack stack = new ImageStack(fi.width, fi.height, cm);
   long skip = fi.getOffset();
   Object pixels;
   try {
     ImageReader reader = new ImageReader(fi);
     InputStream is = createInputStream(fi);
     if (is == null) return null;
     IJ.resetEscape();
     for (int i = 1; i <= fi.nImages; i++) {
       if (!silentMode) IJ.showStatus("Reading: " + i + "/" + fi.nImages);
       if (IJ.escapePressed()) {
         IJ.beep();
         IJ.showProgress(1.0);
         silentMode = false;
         return null;
       }
       pixels = reader.readPixels(is, skip);
       if (pixels == null) break;
       stack.addSlice(null, pixels);
       skip = fi.gapBetweenImages;
       if (!silentMode) IJ.showProgress(i, fi.nImages);
     }
     is.close();
   } catch (Exception e) {
     IJ.log("" + e);
   } catch (OutOfMemoryError e) {
     IJ.outOfMemory(fi.fileName);
     stack.trim();
   }
   if (!silentMode) IJ.showProgress(1.0);
   if (stack.getSize() == 0) return null;
   if (fi.sliceLabels != null && fi.sliceLabels.length <= stack.getSize()) {
     for (int i = 0; i < fi.sliceLabels.length; i++) stack.setSliceLabel(fi.sliceLabels[i], i + 1);
   }
   ImagePlus imp = new ImagePlus(fi.fileName, stack);
   if (fi.info != null) imp.setProperty("Info", fi.info);
   if (show) imp.show();
   imp.setFileInfo(fi);
   setCalibration(imp);
   ImageProcessor ip = imp.getProcessor();
   if (ip.getMin() == ip.getMax()) // find stack min and max if first slice is blank
   setStackDisplayRange(imp);
   if (!silentMode) IJ.showProgress(1.0);
   silentMode = false;
   return imp;
 }
Пример #8
0
  /** Opens the image. Displays it if 'show' is true. Returns an ImagePlus object if successful. */
  public ImagePlus open(boolean show) {
    ImagePlus imp = null;
    Object pixels;
    ProgressBar pb = null;
    ImageProcessor ip;

    ColorModel cm = createColorModel(fi);
    if (fi.nImages > 1) {
      return openStack(cm, show);
    }
    switch (fi.fileType) {
      case FileInfo.GRAY8:
      case FileInfo.COLOR8:
      case FileInfo.BITMAP:
        pixels = readPixels(fi);
        if (pixels == null) return null;
        ip = new ByteProcessor(width, height, (byte[]) pixels, cm);
        imp = new ImagePlus(fi.fileName, ip);
        break;
      case FileInfo.GRAY16_SIGNED:
      case FileInfo.GRAY16_UNSIGNED:
      case FileInfo.GRAY12_UNSIGNED:
        pixels = readPixels(fi);
        if (pixels == null) return null;
        ip = new ShortProcessor(width, height, (short[]) pixels, cm);
        imp = new ImagePlus(fi.fileName, ip);
        break;
      case FileInfo.GRAY32_INT:
      case FileInfo.GRAY32_UNSIGNED:
      case FileInfo.GRAY32_FLOAT:
      case FileInfo.GRAY24_UNSIGNED:
      case FileInfo.GRAY64_FLOAT:
        pixels = readPixels(fi);
        if (pixels == null) return null;
        ip = new FloatProcessor(width, height, (float[]) pixels, cm);
        imp = new ImagePlus(fi.fileName, ip);
        break;
      case FileInfo.RGB:
      case FileInfo.BGR:
      case FileInfo.ARGB:
      case FileInfo.ABGR:
      case FileInfo.BARG:
      case FileInfo.RGB_PLANAR:
        pixels = readPixels(fi);
        if (pixels == null) return null;
        ip = new ColorProcessor(width, height, (int[]) pixels);
        imp = new ImagePlus(fi.fileName, ip);
        break;
      case FileInfo.RGB48:
      case FileInfo.RGB48_PLANAR:
        boolean planar = fi.fileType == FileInfo.RGB48_PLANAR;
        Object[] pixelArray = (Object[]) readPixels(fi);
        if (pixelArray == null) return null;
        ImageStack stack = new ImageStack(width, height);
        stack.addSlice("Red", pixelArray[0]);
        stack.addSlice("Green", pixelArray[1]);
        stack.addSlice("Blue", pixelArray[2]);
        imp = new ImagePlus(fi.fileName, stack);
        imp.setDimensions(3, 1, 1);
        if (planar) imp.getProcessor().resetMinAndMax();
        imp.setFileInfo(fi);
        int mode = CompositeImage.COMPOSITE;
        if (fi.description != null) {
          if (fi.description.indexOf("mode=color") != -1) mode = CompositeImage.COLOR;
          else if (fi.description.indexOf("mode=gray") != -1) mode = CompositeImage.GRAYSCALE;
        }
        imp = new CompositeImage(imp, mode);
        if (!planar && fi.displayRanges == null) {
          for (int c = 1; c <= 3; c++) {
            imp.setPosition(c, 1, 1);
            imp.setDisplayRange(minValue, maxValue);
          }
          imp.setPosition(1, 1, 1);
        }
        break;
    }
    imp.setFileInfo(fi);
    setCalibration(imp);
    if (fi.info != null) imp.setProperty("Info", fi.info);
    if (fi.sliceLabels != null && fi.sliceLabels.length == 1 && fi.sliceLabels[0] != null)
      imp.setProperty("Label", fi.sliceLabels[0]);
    if (show) imp.show();
    return imp;
  }
Пример #9
0
  public void build_bricks() {

    ImagePlus imp;
    ImagePlus orgimp;
    ImageStack stack;
    FileInfo finfo;

    if (lvImgTitle.isEmpty()) return;
    orgimp = WindowManager.getImage(lvImgTitle.get(0));
    imp = orgimp;

    finfo = imp.getFileInfo();
    if (finfo == null) return;

    int[] dims = imp.getDimensions();
    int imageW = dims[0];
    int imageH = dims[1];
    int nCh = dims[2];
    int imageD = dims[3];
    int nFrame = dims[4];
    int bdepth = imp.getBitDepth();
    double xspc = finfo.pixelWidth;
    double yspc = finfo.pixelHeight;
    double zspc = finfo.pixelDepth;
    double z_aspect = Math.max(xspc, yspc) / zspc;

    int orgW = imageW;
    int orgH = imageH;
    int orgD = imageD;
    double orgxspc = xspc;
    double orgyspc = yspc;
    double orgzspc = zspc;

    lv = lvImgTitle.size();
    if (filetype == "JPEG") {
      for (int l = 0; l < lv; l++) {
        if (WindowManager.getImage(lvImgTitle.get(l)).getBitDepth() != 8) {
          IJ.error("A SOURCE IMAGE MUST BE 8BIT GLAYSCALE");
          return;
        }
      }
    }

    // calculate levels
    /*		int baseXY = 256;
    		int baseZ = 256;

    		if (z_aspect < 0.5) baseZ = 128;
    		if (z_aspect > 2.0) baseXY = 128;
    		if (z_aspect >= 0.5 && z_aspect < 1.0) baseZ = (int)(baseZ*z_aspect);
    		if (z_aspect > 1.0 && z_aspect <= 2.0) baseXY = (int)(baseXY/z_aspect);

    		IJ.log("Z_aspect: " + z_aspect);
    		IJ.log("BaseXY: " + baseXY);
    		IJ.log("BaseZ: " + baseZ);
    */

    int baseXY = 256;
    int baseZ = 128;
    int dbXY = Math.max(orgW, orgH) / baseXY;
    if (Math.max(orgW, orgH) % baseXY > 0) dbXY *= 2;
    int dbZ = orgD / baseZ;
    if (orgD % baseZ > 0) dbZ *= 2;
    lv = Math.max(log2(dbXY), log2(dbZ)) + 1;

    int ww = orgW;
    int hh = orgH;
    int dd = orgD;
    for (int l = 0; l < lv; l++) {
      int bwnum = ww / baseXY;
      if (ww % baseXY > 0) bwnum++;
      int bhnum = hh / baseXY;
      if (hh % baseXY > 0) bhnum++;
      int bdnum = dd / baseZ;
      if (dd % baseZ > 0) bdnum++;

      if (bwnum % 2 == 0) bwnum++;
      if (bhnum % 2 == 0) bhnum++;
      if (bdnum % 2 == 0) bdnum++;

      int bw = (bwnum <= 1) ? ww : ww / bwnum + 1 + (ww % bwnum > 0 ? 1 : 0);
      int bh = (bhnum <= 1) ? hh : hh / bhnum + 1 + (hh % bhnum > 0 ? 1 : 0);
      int bd = (bdnum <= 1) ? dd : dd / bdnum + 1 + (dd % bdnum > 0 ? 1 : 0);

      bwlist.add(bw);
      bhlist.add(bh);
      bdlist.add(bd);

      IJ.log("LEVEL: " + l);
      IJ.log("  width: " + ww);
      IJ.log("  hight: " + hh);
      IJ.log("  depth: " + dd);
      IJ.log("  bw: " + bw);
      IJ.log("  bh: " + bh);
      IJ.log("  bd: " + bd);

      int xyl2 = Math.max(ww, hh) / baseXY;
      if (Math.max(ww, hh) % baseXY > 0) xyl2 *= 2;
      if (lv - 1 - log2(xyl2) <= l) {
        ww /= 2;
        hh /= 2;
      }
      IJ.log("  xyl2: " + (lv - 1 - log2(xyl2)));

      int zl2 = dd / baseZ;
      if (dd % baseZ > 0) zl2 *= 2;
      if (lv - 1 - log2(zl2) <= l) dd /= 2;
      IJ.log("  zl2: " + (lv - 1 - log2(zl2)));

      if (l < lv - 1) {
        lvImgTitle.add(lvImgTitle.get(0) + "_level" + (l + 1));
        IJ.selectWindow(lvImgTitle.get(0));
        IJ.run(
            "Scale...",
            "x=- y=- z=- width="
                + ww
                + " height="
                + hh
                + " depth="
                + dd
                + " interpolation=Bicubic average process create title="
                + lvImgTitle.get(l + 1));
      }
    }

    for (int l = 0; l < lv; l++) {
      IJ.log(lvImgTitle.get(l));
    }

    Document doc = newXMLDocument();
    Element root = doc.createElement("BRK");
    root.setAttribute("version", "1.0");
    root.setAttribute("nLevel", String.valueOf(lv));
    root.setAttribute("nChannel", String.valueOf(nCh));
    root.setAttribute("nFrame", String.valueOf(nFrame));
    doc.appendChild(root);

    for (int l = 0; l < lv; l++) {
      IJ.showProgress(0.0);

      int[] dims2 = imp.getDimensions();
      IJ.log(
          "W: "
              + String.valueOf(dims2[0])
              + " H: "
              + String.valueOf(dims2[1])
              + " C: "
              + String.valueOf(dims2[2])
              + " D: "
              + String.valueOf(dims2[3])
              + " T: "
              + String.valueOf(dims2[4])
              + " b: "
              + String.valueOf(bdepth));

      bw = bwlist.get(l).intValue();
      bh = bhlist.get(l).intValue();
      bd = bdlist.get(l).intValue();

      boolean force_pow2 = false;
      /*			if(IsPowerOf2(bw) && IsPowerOf2(bh) && IsPowerOf2(bd)) force_pow2 = true;

      			if(force_pow2){
      				//force pow2
      				if(Pow2(bw) > bw) bw = Pow2(bw)/2;
      				if(Pow2(bh) > bh) bh = Pow2(bh)/2;
      				if(Pow2(bd) > bd) bd = Pow2(bd)/2;
      			}

      			if(bw > imageW) bw = (Pow2(imageW) == imageW) ? imageW : Pow2(imageW)/2;
      			if(bh > imageH) bh = (Pow2(imageH) == imageH) ? imageH : Pow2(imageH)/2;
      			if(bd > imageD) bd = (Pow2(imageD) == imageD) ? imageD : Pow2(imageD)/2;

      */
      if (bw > imageW) bw = imageW;
      if (bh > imageH) bh = imageH;
      if (bd > imageD) bd = imageD;

      if (bw <= 1 || bh <= 1 || bd <= 1) break;

      if (filetype == "JPEG" && (bw < 8 || bh < 8)) break;

      Element lvnode = doc.createElement("Level");
      lvnode.setAttribute("lv", String.valueOf(l));
      lvnode.setAttribute("imageW", String.valueOf(imageW));
      lvnode.setAttribute("imageH", String.valueOf(imageH));
      lvnode.setAttribute("imageD", String.valueOf(imageD));
      lvnode.setAttribute("xspc", String.valueOf(xspc));
      lvnode.setAttribute("yspc", String.valueOf(yspc));
      lvnode.setAttribute("zspc", String.valueOf(zspc));
      lvnode.setAttribute("bitDepth", String.valueOf(bdepth));
      root.appendChild(lvnode);

      Element brksnode = doc.createElement("Bricks");
      brksnode.setAttribute("brick_baseW", String.valueOf(bw));
      brksnode.setAttribute("brick_baseH", String.valueOf(bh));
      brksnode.setAttribute("brick_baseD", String.valueOf(bd));
      lvnode.appendChild(brksnode);

      ArrayList<Brick> bricks = new ArrayList<Brick>();
      int mw, mh, md, mw2, mh2, md2;
      double tx0, ty0, tz0, tx1, ty1, tz1;
      double bx0, by0, bz0, bx1, by1, bz1;
      for (int k = 0; k < imageD; k += bd) {
        if (k > 0) k--;
        for (int j = 0; j < imageH; j += bh) {
          if (j > 0) j--;
          for (int i = 0; i < imageW; i += bw) {
            if (i > 0) i--;
            mw = Math.min(bw, imageW - i);
            mh = Math.min(bh, imageH - j);
            md = Math.min(bd, imageD - k);

            if (force_pow2) {
              mw2 = Pow2(mw);
              mh2 = Pow2(mh);
              md2 = Pow2(md);
            } else {
              mw2 = mw;
              mh2 = mh;
              md2 = md;
            }

            if (filetype == "JPEG") {
              if (mw2 < 8) mw2 = 8;
              if (mh2 < 8) mh2 = 8;
            }

            tx0 = i == 0 ? 0.0d : ((mw2 - mw + 0.5d) / mw2);
            ty0 = j == 0 ? 0.0d : ((mh2 - mh + 0.5d) / mh2);
            tz0 = k == 0 ? 0.0d : ((md2 - md + 0.5d) / md2);

            tx1 = 1.0d - 0.5d / mw2;
            if (mw < bw) tx1 = 1.0d;
            if (imageW - i == bw) tx1 = 1.0d;

            ty1 = 1.0d - 0.5d / mh2;
            if (mh < bh) ty1 = 1.0d;
            if (imageH - j == bh) ty1 = 1.0d;

            tz1 = 1.0d - 0.5d / md2;
            if (md < bd) tz1 = 1.0d;
            if (imageD - k == bd) tz1 = 1.0d;

            bx0 = i == 0 ? 0.0d : (i + 0.5d) / (double) imageW;
            by0 = j == 0 ? 0.0d : (j + 0.5d) / (double) imageH;
            bz0 = k == 0 ? 0.0d : (k + 0.5d) / (double) imageD;

            bx1 = Math.min((i + bw - 0.5d) / (double) imageW, 1.0d);
            if (imageW - i == bw) bx1 = 1.0d;

            by1 = Math.min((j + bh - 0.5d) / (double) imageH, 1.0d);
            if (imageH - j == bh) by1 = 1.0d;

            bz1 = Math.min((k + bd - 0.5d) / (double) imageD, 1.0d);
            if (imageD - k == bd) bz1 = 1.0d;

            int x, y, z;
            x = i - (mw2 - mw);
            y = j - (mh2 - mh);
            z = k - (md2 - md);
            bricks.add(
                new Brick(
                    x, y, z, mw2, mh2, md2, 0, 0, tx0, ty0, tz0, tx1, ty1, tz1, bx0, by0, bz0, bx1,
                    by1, bz1));
          }
        }
      }

      Element fsnode = doc.createElement("Files");
      lvnode.appendChild(fsnode);

      stack = imp.getStack();

      int totalbricknum = nFrame * nCh * bricks.size();
      int curbricknum = 0;
      for (int f = 0; f < nFrame; f++) {
        for (int ch = 0; ch < nCh; ch++) {
          int sizelimit = bdsizelimit * 1024 * 1024;
          int bytecount = 0;
          int filecount = 0;
          int pd_bufsize = Math.max(sizelimit, bw * bh * bd * bdepth / 8);
          byte[] packed_data = new byte[pd_bufsize];
          String base_dataname =
              basename
                  + "_Lv"
                  + String.valueOf(l)
                  + "_Ch"
                  + String.valueOf(ch)
                  + "_Fr"
                  + String.valueOf(f);
          String current_dataname = base_dataname + "_data" + filecount;

          Brick b_first = bricks.get(0);
          if (b_first.z_ != 0) IJ.log("warning");
          int st_z = b_first.z_;
          int ed_z = b_first.z_ + b_first.d_;
          LinkedList<ImageProcessor> iplist = new LinkedList<ImageProcessor>();
          for (int s = st_z; s < ed_z; s++)
            iplist.add(stack.getProcessor(imp.getStackIndex(ch + 1, s + 1, f + 1)));

          //					ImagePlus test;
          //					ImageStack tsst;
          //					test = NewImage.createByteImage("test", imageW, imageH, imageD,
          // NewImage.FILL_BLACK);
          //					tsst = test.getStack();
          for (int i = 0; i < bricks.size(); i++) {
            Brick b = bricks.get(i);

            if (ed_z > b.z_ || st_z < b.z_ + b.d_) {
              if (b.z_ > st_z) {
                for (int s = 0; s < b.z_ - st_z; s++) iplist.pollFirst();
                st_z = b.z_;
              } else if (b.z_ < st_z) {
                IJ.log("warning");
                for (int s = st_z - 1; s > b.z_; s--)
                  iplist.addFirst(stack.getProcessor(imp.getStackIndex(ch + 1, s + 1, f + 1)));
                st_z = b.z_;
              }

              if (b.z_ + b.d_ > ed_z) {
                for (int s = ed_z; s < b.z_ + b.d_; s++)
                  iplist.add(stack.getProcessor(imp.getStackIndex(ch + 1, s + 1, f + 1)));
                ed_z = b.z_ + b.d_;
              } else if (b.z_ + b.d_ < ed_z) {
                IJ.log("warning");
                for (int s = 0; s < ed_z - (b.z_ + b.d_); s++) iplist.pollLast();
                ed_z = b.z_ + b.d_;
              }
            } else {
              IJ.log("warning");
              iplist.clear();
              st_z = b.z_;
              ed_z = b.z_ + b.d_;
              for (int s = st_z; s < ed_z; s++)
                iplist.add(stack.getProcessor(imp.getStackIndex(ch + 1, s + 1, f + 1)));
            }

            if (iplist.size() != b.d_) {
              IJ.log("Stack Error");
              return;
            }

            //						int zz = st_z;

            int bsize = 0;
            byte[] bdata = new byte[b.w_ * b.h_ * b.d_ * bdepth / 8];
            Iterator<ImageProcessor> ipite = iplist.iterator();
            while (ipite.hasNext()) {

              //							ImageProcessor tsip = tsst.getProcessor(zz+1);

              ImageProcessor ip = ipite.next();
              ip.setRoi(b.x_, b.y_, b.w_, b.h_);
              if (bdepth == 8) {
                byte[] data = (byte[]) ip.crop().getPixels();
                System.arraycopy(data, 0, bdata, bsize, data.length);
                bsize += data.length;
              } else if (bdepth == 16) {
                ByteBuffer buffer = ByteBuffer.allocate(b.w_ * b.h_ * bdepth / 8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                short[] data = (short[]) ip.crop().getPixels();
                for (short e : data) buffer.putShort(e);
                System.arraycopy(buffer.array(), 0, bdata, bsize, buffer.array().length);
                bsize += buffer.array().length;
              } else if (bdepth == 32) {
                ByteBuffer buffer = ByteBuffer.allocate(b.w_ * b.h_ * bdepth / 8);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                float[] data = (float[]) ip.crop().getPixels();
                for (float e : data) buffer.putFloat(e);
                System.arraycopy(buffer.array(), 0, bdata, bsize, buffer.array().length);
                bsize += buffer.array().length;
              }
            }

            String filename =
                basename
                    + "_Lv"
                    + String.valueOf(l)
                    + "_Ch"
                    + String.valueOf(ch)
                    + "_Fr"
                    + String.valueOf(f)
                    + "_ID"
                    + String.valueOf(i);

            int offset = bytecount;
            int datasize = bdata.length;

            if (filetype == "RAW") {
              int dummy = -1;
              // do nothing
            }
            if (filetype == "JPEG" && bdepth == 8) {
              try {
                DataBufferByte db = new DataBufferByte(bdata, datasize);
                Raster raster = Raster.createPackedRaster(db, b.w_, b.h_ * b.d_, 8, null);
                BufferedImage img =
                    new BufferedImage(b.w_, b.h_ * b.d_, BufferedImage.TYPE_BYTE_GRAY);
                img.setData(raster);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
                String format = "jpg";
                Iterator<javax.imageio.ImageWriter> iter =
                    ImageIO.getImageWritersByFormatName("jpeg");
                javax.imageio.ImageWriter writer = iter.next();
                ImageWriteParam iwp = writer.getDefaultWriteParam();
                iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                iwp.setCompressionQuality((float) jpeg_quality * 0.01f);
                writer.setOutput(ios);
                writer.write(null, new IIOImage(img, null, null), iwp);
                // ImageIO.write(img, format, baos);
                bdata = baos.toByteArray();
                datasize = bdata.length;
              } catch (IOException e) {
                e.printStackTrace();
                return;
              }
            }
            if (filetype == "ZLIB") {
              byte[] tmpdata = new byte[b.w_ * b.h_ * b.d_ * bdepth / 8];
              Deflater compresser = new Deflater();
              compresser.setInput(bdata);
              compresser.setLevel(Deflater.DEFAULT_COMPRESSION);
              compresser.setStrategy(Deflater.DEFAULT_STRATEGY);
              compresser.finish();
              datasize = compresser.deflate(tmpdata);
              bdata = tmpdata;
              compresser.end();
            }

            if (bytecount + datasize > sizelimit && bytecount > 0) {
              BufferedOutputStream fis = null;
              try {
                File file = new File(directory + current_dataname);
                fis = new BufferedOutputStream(new FileOutputStream(file));
                fis.write(packed_data, 0, bytecount);
              } catch (IOException e) {
                e.printStackTrace();
                return;
              } finally {
                try {
                  if (fis != null) fis.close();
                } catch (IOException e) {
                  e.printStackTrace();
                  return;
                }
              }
              filecount++;
              current_dataname = base_dataname + "_data" + filecount;
              bytecount = 0;
              offset = 0;
              System.arraycopy(bdata, 0, packed_data, bytecount, datasize);
              bytecount += datasize;
            } else {
              System.arraycopy(bdata, 0, packed_data, bytecount, datasize);
              bytecount += datasize;
            }

            Element filenode = doc.createElement("File");
            filenode.setAttribute("filename", current_dataname);
            filenode.setAttribute("channel", String.valueOf(ch));
            filenode.setAttribute("frame", String.valueOf(f));
            filenode.setAttribute("brickID", String.valueOf(i));
            filenode.setAttribute("offset", String.valueOf(offset));
            filenode.setAttribute("datasize", String.valueOf(datasize));
            filenode.setAttribute("filetype", String.valueOf(filetype));

            fsnode.appendChild(filenode);

            curbricknum++;
            IJ.showProgress((double) (curbricknum) / (double) (totalbricknum));
          }
          if (bytecount > 0) {
            BufferedOutputStream fis = null;
            try {
              File file = new File(directory + current_dataname);
              fis = new BufferedOutputStream(new FileOutputStream(file));
              fis.write(packed_data, 0, bytecount);
            } catch (IOException e) {
              e.printStackTrace();
              return;
            } finally {
              try {
                if (fis != null) fis.close();
              } catch (IOException e) {
                e.printStackTrace();
                return;
              }
            }
          }
        }
      }

      for (int i = 0; i < bricks.size(); i++) {
        Brick b = bricks.get(i);
        Element bricknode = doc.createElement("Brick");
        bricknode.setAttribute("id", String.valueOf(i));
        bricknode.setAttribute("st_x", String.valueOf(b.x_));
        bricknode.setAttribute("st_y", String.valueOf(b.y_));
        bricknode.setAttribute("st_z", String.valueOf(b.z_));
        bricknode.setAttribute("width", String.valueOf(b.w_));
        bricknode.setAttribute("height", String.valueOf(b.h_));
        bricknode.setAttribute("depth", String.valueOf(b.d_));
        brksnode.appendChild(bricknode);

        Element tboxnode = doc.createElement("tbox");
        tboxnode.setAttribute("x0", String.valueOf(b.tx0_));
        tboxnode.setAttribute("y0", String.valueOf(b.ty0_));
        tboxnode.setAttribute("z0", String.valueOf(b.tz0_));
        tboxnode.setAttribute("x1", String.valueOf(b.tx1_));
        tboxnode.setAttribute("y1", String.valueOf(b.ty1_));
        tboxnode.setAttribute("z1", String.valueOf(b.tz1_));
        bricknode.appendChild(tboxnode);

        Element bboxnode = doc.createElement("bbox");
        bboxnode.setAttribute("x0", String.valueOf(b.bx0_));
        bboxnode.setAttribute("y0", String.valueOf(b.by0_));
        bboxnode.setAttribute("z0", String.valueOf(b.bz0_));
        bboxnode.setAttribute("x1", String.valueOf(b.bx1_));
        bboxnode.setAttribute("y1", String.valueOf(b.by1_));
        bboxnode.setAttribute("z1", String.valueOf(b.bz1_));
        bricknode.appendChild(bboxnode);
      }

      if (l < lv - 1) {
        imp = WindowManager.getImage(lvImgTitle.get(l + 1));
        int[] newdims = imp.getDimensions();
        imageW = newdims[0];
        imageH = newdims[1];
        imageD = newdims[3];
        xspc = orgxspc * ((double) orgW / (double) imageW);
        yspc = orgyspc * ((double) orgH / (double) imageH);
        zspc = orgzspc * ((double) orgD / (double) imageD);
        bdepth = imp.getBitDepth();
      }
    }

    File newXMLfile = new File(directory + basename + ".vvd");
    writeXML(newXMLfile, doc);

    for (int l = 1; l < lv; l++) {
      imp = WindowManager.getImage(lvImgTitle.get(l));
      imp.changes = false;
      imp.close();
    }
  }
  void boitestack(
      final ImageStack stack1,
      final int nb,
      final double[] xg,
      final double[] yg,
      final double[] zg,
      final double[][][] dir,
      double[][] lmin,
      double[][] lmax) {
    final AtomicInteger ai = new AtomicInteger(0);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final double[][][] lmint = new double[dimZ][nb][3];
    final double[][][] lmaxt = new double[dimZ][nb][3];

    for (int k = 0; k < nb; k++) {
      lmin[k][0] = 100000;
      lmin[k][1] = 100000;
      lmin[k][2] = 100000;
      lmax[k][0] = -100000;
      lmax[k][1] = -100000;
      lmax[k][2] = -100000;
    }

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi < dimZ;
                  superi = ai.getAndIncrement()) {
                int k = superi;
                ImageProcessor ip = stack1.getProcessor(k + 1);
                for (int l = 0; l < nb; l++) {
                  lmint[k][l][0] = 100000;
                  lmint[k][l][1] = 100000;
                  lmint[k][l][2] = 100000;
                  lmaxt[k][l][0] = -100000;
                  lmaxt[k][l][1] = -100000;
                  lmaxt[k][l][2] = -100000;
                }
                for (int j = 0; j < dimY; j++) {
                  for (int i = 0; i < dimX; i++) {
                    int pix = (int) (ip.getPixelValue(i, j));
                    if (pix != 0) {
                      //								double v1 =
                      // (i-xg[pix-2])*dir[0][0][pix-2]+(j-yg[pix-2])*dir[1][0][pix-2]+(k-zg[pix-2])*dir[2][0][pix-2];
                      //							    double v2 =
                      // (i-xg[pix-2])*dir[0][1][pix-2]+(j-yg[pix-2])*dir[1][1][pix-2]+(k-zg[pix-2])*dir[2][1][pix-2];
                      //							    double v3 =
                      // (i-xg[pix-2])*dir[0][2][pix-2]+(j-yg[pix-2])*dir[1][2][pix-2]+(k-zg[pix-2])*dir[2][2][pix-2];
                      //							    if (v1<lmint[k][pix-2][0]) lmint[k][pix-2][0]=v1;
                      //							    if (v1>lmaxt[k][pix-2][0]) lmaxt[k][pix-2][0]=v1;
                      //							    if (v2<lmint[k][pix-2][1]) lmint[k][pix-2][1]=v2;
                      //							    if (v2>lmaxt[k][pix-2][1]) lmaxt[k][pix-2][1]=v2;
                      //							    if (v3<lmint[k][pix-2][2]) lmint[k][pix-2][2]=v3;
                      //							    if (v3>lmaxt[k][pix-2][2]) lmaxt[k][pix-2][2]=v3;
                      double v1 =
                          (i - xg[pix - 1]) * dir[0][0][pix - 1]
                              + (j - yg[pix - 1]) * dir[1][0][pix - 1]
                              + (k - zg[pix - 1]) * dir[2][0][pix - 1];
                      double v2 =
                          (i - xg[pix - 1]) * dir[0][1][pix - 1]
                              + (j - yg[pix - 1]) * dir[1][1][pix - 1]
                              + (k - zg[pix - 1]) * dir[2][1][pix - 1];
                      double v3 =
                          (i - xg[pix - 1]) * dir[0][2][pix - 1]
                              + (j - yg[pix - 1]) * dir[1][2][pix - 1]
                              + (k - zg[pix - 1]) * dir[2][2][pix - 1];
                      if (v1 < lmint[k][pix - 1][0]) lmint[k][pix - 1][0] = v1;
                      if (v1 > lmaxt[k][pix - 1][0]) lmaxt[k][pix - 1][0] = v1;
                      if (v2 < lmint[k][pix - 1][1]) lmint[k][pix - 1][1] = v2;
                      if (v2 > lmaxt[k][pix - 1][1]) lmaxt[k][pix - 1][1] = v2;
                      if (v3 < lmint[k][pix - 1][2]) lmint[k][pix - 1][2] = v3;
                      if (v3 > lmaxt[k][pix - 1][2]) lmaxt[k][pix - 1][2] = v3;
                    }
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);
    for (int i = 0; i < dimZ; i++) {
      for (int j = 0; j < nb; j++) {
        for (int l = 0; l < 3; l++) {
          if (lmint[i][j][l] < lmin[j][l]) lmin[j][l] = lmint[i][j][l];
          if (lmaxt[i][j][l] > lmax[j][l]) lmax[j][l] = lmaxt[i][j][l];
        }
      }
      lmint[i] = null;
      lmaxt[i] = null;
    }
  }
  void calculinertiestack(
      final ImageStack stack1,
      int nb,
      final double[] xg,
      final double[] yg,
      final double[] zg,
      double[][][] I) {
    final AtomicInteger ai = new AtomicInteger(0);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final double[][][][] inert = new double[dimZ][nb][3][3];

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi < dimZ;
                  superi = ai.getAndIncrement()) {
                int k = superi;
                ImageProcessor ip = stack1.getProcessor(k + 1);
                for (int j = 0; j < dimY; j++) {
                  for (int i = 0; i < dimX; i++) {
                    int pix = (int) (ip.getPixelValue(i, j));
                    if (pix != 0) {
                      //
                      // inert[k][pix-2][0][0]+=(i-yg[pix-2])*(i-yg[pix-2])+(k-zg[pix-2])*(k-zg[pix-2])+1.0/6.0;
                      //						         inert[k][pix-2][0][1]-=(j-xg[pix-2])*(i-yg[pix-2]);
                      //						         inert[k][pix-2][0][2]-=(j-xg[pix-2])*(k-zg[pix-2]);
                      //
                      // inert[k][pix-2][1][1]+=(j-xg[pix-2])*(j-xg[pix-2])+(k-zg[pix-2])*(k-zg[pix-2])+1.0/6.0;
                      //						         inert[k][pix-2][1][2]-=(i-yg[pix-2])*(k-zg[pix-2]);
                      //
                      // inert[k][pix-2][2][2]+=(j-xg[pix-2])*(j-xg[pix-2])+(i-yg[pix-2])*(i-yg[pix-2])+1.0/6.0;
                      inert[k][pix - 1][0][0] +=
                          (j - yg[pix - 1]) * (j - yg[pix - 1])
                              + (k - zg[pix - 1]) * (k - zg[pix - 1])
                              + 1.0 / 6.0;
                      inert[k][pix - 1][0][1] -= (i - xg[pix - 1]) * (j - yg[pix - 1]);
                      inert[k][pix - 1][0][2] -= (i - xg[pix - 1]) * (k - zg[pix - 1]);
                      inert[k][pix - 1][1][1] +=
                          (i - xg[pix - 1]) * (i - xg[pix - 1])
                              + (k - zg[pix - 1]) * (k - zg[pix - 1])
                              + 1.0 / 6.0;
                      inert[k][pix - 1][1][2] -= (j - yg[pix - 1]) * (k - zg[pix - 1]);
                      inert[k][pix - 1][2][2] +=
                          (i - xg[pix - 1]) * (i - xg[pix - 1])
                              + (j - yg[pix - 1]) * (j - yg[pix - 1])
                              + 1.0 / 6.0;
                    }
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);
    for (int i = 0; i < dimZ; i++) {
      for (int j = 0; j < nb; j++) {
        for (int l = 0; l < 3; l++) {
          for (int m = 0; m <= l; m++) {
            I[l][m][j] += inert[i][j][l][m];
          }
        }
      }
      inert[i] = null;
    }
    for (int j = 0; j < nb; j++) {
      I[1][0][j] = I[0][1][j];
      I[2][0][j] = I[0][2][j];
      I[2][1][j] = I[1][2][j];
    }
  }
  void calculcgstack(
      final ImageStack stack1,
      int nb,
      final int[] v,
      final double[] xg,
      final double[] yg,
      final double[] zg) {
    final AtomicInteger ai = new AtomicInteger(0);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final int[][] vol = new int[dimZ][nb];
    final int[][] tmpxg = new int[dimZ][nb];
    final int[][] tmpyg = new int[dimZ][nb];
    final int[][] tmpzg = new int[dimZ][nb];

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi < dimZ;
                  superi = ai.getAndIncrement()) {
                int k = superi;
                ImageProcessor ip = stack1.getProcessor(k + 1);
                for (int j = 0; j < dimY; j++) {
                  for (int i = 0; i < dimX; i++) {
                    int pix = (int) (ip.getPixelValue(i, j));
                    if (pix != 0) {
                      //						          tmpxg[k][pix-2] += j;
                      //						          tmpyg[k][pix-2] += i;
                      //						          tmpzg[k][pix-2] += k;
                      //						          vol[k][pix-2]++;
                      tmpxg[k][pix - 1] += i;
                      tmpyg[k][pix - 1] += j;
                      tmpzg[k][pix - 1] += k;
                      vol[k][pix - 1]++;
                    }
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);
    for (int i = 0; i < dimZ; i++) {
      for (int j = 0; j < nb; j++) {
        v[j] += vol[i][j];
        xg[j] += tmpxg[i][j];
        yg[j] += tmpyg[i][j];
        zg[j] += tmpzg[i][j];
      }
    }

    for (int i = 0; i < nb; i++) {
      xg[i] = (1.0 * xg[i] / v[i]);
      yg[i] = (1.0 * yg[i] / v[i]);
      zg[i] = (1.0 * zg[i] / v[i]);
    }
  }
  void calculsurfacemarch3stack(final ImageStack stack1, int nb, final double[] tri, double[] s2) {
    final AtomicInteger ai = new AtomicInteger(0);
    final int dimX = stack1.getWidth();
    final int dimY = stack1.getHeight();
    final int dimZ = stack1.getSize();
    final double[][] surf = new double[dimZ][nb];

    for (int ithread = 0; ithread < threads.length; ithread++) {

      // Concurrently run in as many threads as CPUs

      threads[ithread] =
          new Thread() {

            public void run() {
              for (int superi = ai.getAndIncrement();
                  superi < dimZ - 1;
                  superi = ai.getAndIncrement()) {
                int k = superi;
                ImageProcessor ip1, ip2;
                ip1 = stack1.getProcessor(k + 1);
                ip2 = stack1.getProcessor(k + 2);
                for (int j = 0; j < dimY - 1; j++) {
                  for (int i = 0; i < dimX - 1; i++) {
                    int[] p = new int[8];
                    int p1, p2, p3, p4, p5, p6, p7, p8, ptot;
                    int[] nontab = new int[8];

                    ptot = (short) 0;
                    p[0] = (int) ip1.getPixelValue(i, j);
                    p[1] = (int) ip1.getPixelValue(i, j + 1);
                    p[2] = (int) ip2.getPixelValue(i, j);
                    p[3] = (int) ip2.getPixelValue(i, j + 1);
                    p[4] = (int) ip1.getPixelValue(i + 1, j);
                    p[5] = (int) ip1.getPixelValue(i + 1, j + 1);
                    p[6] = (int) ip2.getPixelValue(i + 1, j);
                    p[7] = (int) ip2.getPixelValue(i + 1, j + 1);

                    int pixcoul = 0;

                    for (int l = 0; l < 8; l++) nontab[l] = 0;

                    int cpt = 0;

                    // look for different colors
                    for (int l = 0; l < 8; l++) {
                      if (p[l] != 0 && appart(p[l], nontab, 8) == 1) {
                        nontab[cpt] = p[l];
                        cpt++;
                      }
                    }

                    for (int mm = 0; mm < cpt; mm++) {
                      p1 = 0;
                      p2 = 0;
                      p3 = 0;
                      p4 = 0;
                      p5 = 0;
                      p6 = 0;
                      p7 = 0;
                      p8 = 0;

                      if (p[0] != 0 && p[0] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p1 = 1;
                      }

                      if (p[1] != 0 && p[1] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p2 = 4;
                      }

                      if (p[2] != 0 && p[2] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p3 = 2;
                      }

                      if (p[3] != 0 && p[3] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p4 = 8;
                      }

                      if (p[4] != 0 && p[4] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p5 = 16;
                      }

                      if (p[5] != 0 && p[5] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p6 = 64;
                      }

                      if (p[6] != 0 && p[6] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p7 = 32;
                      }

                      if (p[7] != 0 && p[7] == nontab[mm]) {
                        pixcoul = nontab[mm];
                        p8 = 128;
                      }

                      ptot = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8);

                      if (pixcoul != 0) {
                        surf[k][(int) (pixcoul - 1)] += tri[(int) (ptot)];
                        // surf[k][(int)(pixcoul-2)]+=tri[(int)(ptot)];
                      }
                    }
                  }
                }
              }
            }
          };
    }
    startAndJoin(threads);
    for (int i = 0; i < dimZ; i++) {
      for (int j = 0; j < nb; j++) {
        s2[j] += surf[i][j];
      }
    }
  }