/* * Copyright (c) 2005–2012 Goethe Center for Scientific Computing - Simulation and Modelling (G-CSC Frankfurt) * Copyright (c) 2012-2015 Goethe Center for Scientific Computing - Computational Neuroscience (G-CSC Frankfurt) * * This file is part of NeuGen. * * NeuGen is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * see: http://opensource.org/licenses/LGPL-3.0 * file://path/to/NeuGen/LICENSE * * NeuGen is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * This version of NeuGen includes copyright notice and attribution requirements. * According to the LGPL this information must be displayed even if you modify * the source code of NeuGen. The copyright statement/attribution may not be removed. * * Attribution Requirements: * * If you create derived work you must do the following regarding copyright * notice and author attribution. * * Add an additional notice, stating that you modified NeuGen. In addition * you must cite the publications listed below. A suitable notice might read * "NeuGen source code modified by YourName 2012". * * Note, that these requirements are in full accordance with the LGPL v3 * (see 7. Additional Terms, b). * * Publications: * * S. Wolf, S. Grein, G. Queisser. NeuGen 2.0 - * Employing NeuGen 2.0 to automatically generate realistic * morphologies of hippocapal neurons and neural networks in 3D. * Neuroinformatics, 2013, 11(2), pp. 137-148, doi: 10.1007/s12021-012-9170-1 * * * J. P. Eberhard, A. Wanner, G. Wittum. NeuGen - * A tool for the generation of realistic morphology * of cortical neurons and neural networks in 3D. * Neurocomputing, 70(1-3), pp. 327-343, doi: 10.1016/j.neucom.2006.01.028 * */ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.neugen.vrl; import com.sun.j3d.loaders.IncorrectFormatException; import com.sun.j3d.loaders.ParsingErrorException; import com.sun.j3d.loaders.Scene; import com.sun.j3d.loaders.objectfile.ObjectFile; import eu.mihosoft.vrl.system.VParamUtil; import ij.ImagePlus; import ij.ImageStack; import ij.process.ImageConverter; import ij.process.ImageProcessor; import ij.process.StackConverter; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.StringTokenizer; import javax.media.j3d.BranchGroup; import javax.media.j3d.Node; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.vecmath.AxisAngle4f; import javax.vecmath.Point3f; import javax.vecmath.Point3i; import javax.vecmath.Vector3f; import org.apache.log4j.Logger; import org.neugen.datastructures.Net; import org.neugen.datastructures.Region; import org.neugen.datastructures.VolumeOfVoxels; import org.neugen.datastructures.VoxelVolume; import org.neugen.datastructures.VoxelVolumeIterator; import org.neugen.gui.DensityDialog; import org.neugen.gui.NeuGenView; import org.neugen.gui.VisualizationTask; import org.neugen.utils.NGImageIO; /** * * @author Michael Hoffer <info@michaelhoffer.de> */ public final class VRLDensityVisualizationTask { DensityVisualizationConfigDialog ngVisConfig; private static final Logger logger = Logger.getLogger(VRLDensityVisualizationTask.class.getName()); private File dir, selectedFile; private float scale = 0.001f; private float scaleZ = 0.001f; private Scene s; public float getScaleZ() { return scaleZ; } public float getScale() { return scale; } void setMyProgress(int thisindex, int i, int voxelArraySize) { // } void setMyProgress(float f) { // } public enum Density { NET, IMAGE; } private Density dens; public VRLDensityVisualizationTask() { // } public VisualizationContext run(File f, Density dens, VoxelParams vDialog) throws Exception { this.dir = f.getParentFile(); this.selectedFile = f; VParamUtil.validate(VParamUtil.VALIDATOR_EXISTING_FILE, selectedFile); VisualizationContext context = null; switch (dens) { case NET: { DensityDialog densDialog = new DensityDialog(NeuGenView.getInstance().getFrame(), true); densDialog.setVisible(true); densDialog.setLocationRelativeTo(null); if (densDialog.getReturnStatus() == DensityDialog.RET_OK) { Point3f volumeEnd = new Point3f(Region.getInstance().getUpRightCorner()); if (VisualizationTask.getInstance() != null) { if (VisualizationTask.getInstance().getNGVisualization() != null) { scale = VisualizationTask.getInstance().getNGVisualization().getScale(); } } volumeEnd.scale(scale); logger.info(volumeEnd.toString()); NeuGenView ngView = NeuGenView.getInstance(); Net net = ngView.getNet(); VoxelVolume vv = new VoxelVolume(net, densDialog.getVoxelLenght(), densDialog.getDensityPart(), densDialog.getDensityMethod()); VoxelVolumeIterator voxelVolumeIterator = new VoxelVolumeIterator(vv); Point3i voxelNumber = voxelVolumeIterator.getVoxelNumber(); VolumeOfVoxels volumeOfVoxels = new VolumeOfVoxels(voxelNumber, volumeEnd); int thisindex = 0; float value; int voxelArraySize = vv.getVoxelArray().size(); while (voxelVolumeIterator.hasNext()) { value = voxelVolumeIterator.next(); volumeOfVoxels.setVoxelValue(thisindex, value); // same index thisindex++; setMyProgress(thisindex, 0, voxelArraySize); } // ngVisConfig = new DensityVisualizationConfigDialog(this,volumeOfVoxels, dens, canvasParent, canvas3D); // DensityVisualizationConfigDialog.setInstance(ngVisConfig); // ngVisConfig.setLocationRelativeTo(null); // ngVisConfig.setVisible(true); } else { NeuGenView.getInstance().enableButtons(); } break; } case IMAGE: { System.out.println("NeuGen.visualType: IMAGE"); //NGImageIO imageIO = new NGImageIO(); //List<ImageProducer> fileList = imageIO.getFileList(dir); logger.info("image density task, dir path: " + dir.getAbsolutePath()); boolean imageSequence = false; // indicates whether processing image sequence ArrayList<int[][]> dataList = new ArrayList<int[][]>(); //int numFiles = fileList.size(); //logger.info("anzahl bilder: " + numFiles); int count = 0; int width = 0; int height = 0; int stackSize = 0; BranchGroup bg = null; //ArrayList<ImageIcon> fileList = new ArrayList<ImageIcon>(); if (dir != null) { File[] listFiles = dir.listFiles(); boolean stackLoaded = false; for (File file : listFiles) { if (NGImageIO.isImage(file.getName())) { if (!imageSequence && !selectedFile.getName().equals(file.getName())) { continue; } System.out.println("image stack name: " + file.getName()); if (stackLoaded && !imageSequence) { logger.info("stack schon geladen!"); continue; } try { /* Image img = Jimi.getImage(file.getAbsolutePath()); ImageIcon imgIcon = new ImageIcon(img); fileList.add(imgIcon); * */ logger.info("file name: " + file.getName()); ImagePlus imp = ij.IJ.openImage(file.getAbsolutePath()); stackSize = imp.getStackSize(); if (stackSize > 1) { StackConverter sc = new StackConverter(imp); sc.convertToGray8(); } else { count++; ImageConverter im = new ImageConverter(imp); im.convertToGray8(); } ImageStack stack = imp.getStack(); if (stack.getSize() > 1) { stackLoaded = true; } for (int i = 1; i <= stack.getSize(); i++) { ImageProcessor ip = stack.getProcessor(i); byte[] pixels = (byte[]) ip.getPixels(); width = ip.getWidth(); height = ip.getHeight(); //Array zu Matrix konvertieren int[][] bildMatrix = new int[width][height]; int x = 0; //Anfangswert fuer x int y = 0; //Anfangswert fuer y //fuer alle Elemente des Feldes for (int j = 0; j < width * height; j++) { //wenn alle Elemente der Reihe durchlaufen if (x == width) { x = 0; //mit dem ersten Element y++; //der naechsten Reihe beginnen }//if bildMatrix[x][y] = pixels[j]; x++; //naechstes Element }//for dataList.add(bildMatrix); } } catch (Exception ex) { logger.error(ex, ex); } } else if (NGImageIO.isGeom(file.getName())) { bg = getGeom(file); } System.out.println(">> stack loaded"); } /* for (ImageIcon image : fileList) { //Image image = ngView.getFrame().createImage(imageProd); //image.flush(); //System.out.println(image.getIconHeight()); //System.out.println(image.getIconWidth()); try { PixelGrabber grabber = new PixelGrabber(image.getImage(), 0, 0, -1, -1, false); if (grabber.grabPixels()) { int width = grabber.getWidth(); int height = grabber.getHeight(); int[][] data = imageIO.getData(image.getImage(), width, height); dataList.add(data); //setMyProgress(count, 0, numFiles); } else { logger.info("geht nichts.."); } } catch (InterruptedException ex) { logger.error(ex, ex); } count++; } * */ // ngView.outPrintln("image stack size: " + dataList.size()); logger.info("image density task, anzahl bilder: " + dataList.size()); Point3i voxelLength = vDialog.getVoxelLength(); logger.info("voxelLenght: " + voxelLength.toString()); int intensity = vDialog.getThreshold(); int weight = vDialog.getWeight(); float scannedImgHeight = vDialog.getHeight(); float scannedImgWidth = vDialog.getWidth(); float scannedDepth = vDialog.getDepth(); logger.info("scanned height: " + scannedImgHeight); logger.info("scanned width: " + scannedImgWidth); logger.info("scanned depth: " + scannedDepth); //this.scale = 0.0065f; //this.scale = 0.01f; //this.scale = 0.0077f; this.scale = scannedImgHeight / height; //um pro pixel this.scale /= 10.0f; //float scaleZ = 0.0498f / 5.0f; float optDepth = 0.1f; float faktor = scannedDepth / optDepth; scaleZ = 0.0f; if (stackSize > 0) { float stackDepth = stackSize * scannedDepth; logger.info("tiefe: " + stackDepth); scaleZ = scannedDepth; scaleZ /= 10.0f; } else { scaleZ = scannedDepth / faktor; scaleZ /= 10.0f; } // scale *= 2.f; // scaleZ *= 2.f; logger.info("scale: " + scale); logger.info("scaleZ: " + scaleZ); logger.info("stack size: " + stackSize); VoxelVolume vv = new VoxelVolume(dataList, voxelLength, intensity, weight); Point3f volumeEnd = new Point3f(Region.getInstance().getUpRightCorner()); logger.info("volumeEnd: " + volumeEnd.toString()); volumeEnd.x *= scale; volumeEnd.z *= scale; volumeEnd.y *= scaleZ; VoxelVolumeIterator voxelVolumeIterator = new VoxelVolumeIterator(vv); Point3i voxelNumber = voxelVolumeIterator.getVoxelNumber(); VolumeOfVoxels volumeOfVoxels = new VolumeOfVoxels(voxelNumber, volumeEnd); int thisindex = 0; float value = 0.0f; int voxelArraySize = vv.getVoxelArray().size(); while (voxelVolumeIterator.hasNext()) { value = voxelVolumeIterator.next(); volumeOfVoxels.setVoxelValue(thisindex, value); // same index thisindex++; setMyProgress(thisindex, 0, voxelArraySize); } context = new VisualizationContext(bg, volumeOfVoxels, scale, scaleZ); } else { NeuGenView.getInstance().enableButtons(); } break; } } return context; } private BranchGroup getGeom(File file) throws FileNotFoundException, IOException { Reader in = new FileReader(file); BufferedReader lineReader = new BufferedReader(in); String nextLine = null; nextLine = lineReader.readLine().trim(); String[] dataArray = nextLine.split(" "); int numVertices = Integer.parseInt(dataArray[0]); int numTriangles = Integer.parseInt(dataArray[1]); logger.info("first line: " + nextLine); logger.info("vertices: " + numVertices); logger.info("faces:" + numTriangles); System.out.println("first line: " + nextLine); System.out.println("vertices: " + numVertices); System.out.println("faces:" + numTriangles); // compute min/max // TxT2Geometry loader = new TxT2Geometry(); // VTriangleArray geometry = loader.loadAsVTriangleArray(file); // geometry.centerNodes(); // Appearance app = AppearanceGenerator.getSolidAppearance(Color.red, true); // BranchGroup result = new BranchGroup(); // result.addChild(new Shape3D(geometry.getTriangleArray(),app)); // if (true) { // return result; // } StringBuilder sb = new StringBuilder(); for (int i = 0; i < numVertices; i++) { nextLine = lineReader.readLine().trim(); StringTokenizer st = new StringTokenizer(nextLine); st.nextToken(); sb.append('v').append(' '); sb.append(st.nextToken()).append(' '); sb.append(st.nextToken()).append(' '); sb.append(st.nextToken()).append('\n'); } for (int i = 0; i < numTriangles; i++) { nextLine = lineReader.readLine().trim(); StringTokenizer st = new StringTokenizer(nextLine); st.nextToken(); int v1 = Integer.parseInt(st.nextToken()) + 1; int v2 = Integer.parseInt(st.nextToken()) + 1; int v3 = Integer.parseInt(st.nextToken()) + 1; sb.append('f').append(' '); sb.append(v1).append(' '); sb.append(v2).append(' '); sb.append(v3).append('\n'); } Reader sr = new StringReader(sb.toString()); int flags = ObjectFile.RESIZE | ObjectFile.STRIPIFY | ObjectFile.TRIANGULATE; ObjectFile f = new ObjectFile(flags, (float) (60.0 * Math.PI / 180.0)); try { s = f.load(sr); } catch (FileNotFoundException e) { logger.error(e); System.exit(1); } catch (ParsingErrorException e) { logger.error(e); System.exit(1); } catch (IncorrectFormatException e) { logger.error(e); System.exit(1); } /* TransformGroup objScale = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.setScale(1.0); objScale.setTransform(t3d); s.getSceneGroup().addChild(objScale); * */ Node bg = s.getSceneGroup();//.cloneTree(); Transform3D transRot = new Transform3D(); TransformGroup tg = new TransformGroup(); tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); tg.setCapability(TransformGroup.ENABLE_PICK_REPORTING); Vector3f cross2 = new Vector3f(1.0f, 0.0f, 0.0f); transRot.setRotation(new AxisAngle4f(cross2, (float) Math.toRadians(90))); tg.setTransform(transRot); tg.addChild(bg); BranchGroup result = new BranchGroup(); result.addChild(tg); return result; } // protected void succeeded(Void result) { // System.gc(); // NeuGenView ngView = NeuGenView.getInstance(); // ngView.outPrintln(Utils.getMemoryStatus()); // ngView.enableVisualizeDensity(); // ngView.enableVisualize(); // switch (dens) { // case IMAGE: { // ngView.enableWriteNeuGenBG(); // } // } // } }