/** * @param img * @return the inferred mapping */ private static int[] getInferredMapping(final ImgPlus<?> img) { int[] inferredMapping = new int[DEFAULT_IJ1_MAPPING.size()]; Arrays.fill(inferredMapping, -1); for (int d = 0; d < img.numDimensions(); d++) { inferredMapping[d] = DEFAULT_IJ1_MAPPING.get(img.axis(d).type()); } int offset = 0; for (AxisType type : DEFAULT_IJ1_MAPPING.keySet()) { boolean contains = false; for (int d = 0; d < img.numDimensions(); d++) { if (img.axis(d).type().equals(type)) { contains = true; break; } } if (!contains) { inferredMapping[img.numDimensions() + offset] = DEFAULT_IJ1_MAPPING.get(type); offset++; } } return inferredMapping; }
/** * Check if ImgPlus contains axis which can not be mapped to IJ ImagePlus. Valid axes in ImagePlus * are X, Y, Channel, Z, Time. * * @param img * @return true if mapping is valid */ public static boolean validateMapping(final ImgPlus<?> img) { for (int d = 0; d < img.numDimensions(); d++) { if (DEFAULT_IJ1_MAPPING.get(((DefaultTypedAxis) img.axis(d)).type()) == null) { return false; } } return true; }
/** * @param img * @return calibration */ public static double[] getNewCalibration(final ImgPlus<?> img) { int[] mapping = getInferredMapping(img); // also map/swap calibration double[] newCalib = new double[mapping.length]; for (int i = 0; i < img.numDimensions(); i++) { newCalib[mapping[i]] = img.averageScale(i); } return newCalib; }
private void setUpAxes(final ImgPlus<T> image) { final CalibratedAxis[] axes = new CalibratedAxis[image.numDimensions()]; image.axes(axes); final List<Viewer3DNodeAxis> axesList = new LinkedList<Viewer3DNodeAxis>(); for (final TypedAxis a : axes) { final long extent = image.dimension(image.dimensionIndex(a.type())); axesList.add(new Viewer3DNodeAxis(a, (int) extent, image.dimensionIndex(a.type()))); } m_axes = new Viewer3DNodeAxes(Viewer3DNodeImageToVTK.getMinDims(), axesList); }
/** * Extends the given {@link ImgPlus} to 5-dimensions and makes sure, that the dimension order * suits IJ. * * @param img to be extended and permuted * @return extended and permuted {@link Img} */ public static <T> RandomAccessibleInterval<T> extendAndPermute(final ImgPlus<T> img) { // Create Mapping [at position one -> new index, at position 2 -> new index etc.] given: ImgPlus // and m_mapping // we always want to have 5 dimensions RandomAccessibleInterval<T> extended = img; for (int d = img.numDimensions(); d < 5; d++) { extended = Views.addDimension(extended, 0, 0); } return DimSwapper.swap(extended, getInferredMapping(img)); }
private UnaryOutputOperation<ImgPlus<T>, ImgPlus<V>> getSlidingOperation( final ImgPlus<T> img, final V type) { final Shape neighborhood = NeighborhoodType.getNeighborhood( NeighborhoodType.valueOf(m_neighborhoodType.getStringValue()), m_intervalExtend.getIntValue()); final OutOfBoundsFactory<T, ImgPlus<T>> outStrat = OutOfBoundsStrategyFactory.<T, ImgPlus<T>>getStrategy( m_outOfBoundsStrategy.getStringValue(), img.firstElement()); return getSlidingOperation(img, type, neighborhood, outStrat); }
public static void main(final String[] args) { // TEST 2D case // Parameters final int size_x = 200; final int size_y = 200; final long a = 10; final long b = 5; final double phi_r = Math.toRadians(30); final long max_radius = Math.max(a, b); final double[] calibration = new double[] {1, 1}; // Create blank image final Img<UnsignedByteType> img = new ArrayImgFactory<UnsignedByteType>() .create(new int[] {200, 200}, new UnsignedByteType()); final ImgPlus<UnsignedByteType> imgplus = new ImgPlus<UnsignedByteType>(img); for (int d = 0; d < imgplus.numDimensions(); d++) { imgplus.setAxis(new DefaultLinearAxis(imgplus.axis(d).type(), calibration[d]), d); } final byte on = (byte) 255; // Create an ellipse long start = System.currentTimeMillis(); System.out.println(String.format("Creating an ellipse with a = %d, b = %d", a, b)); System.out.println(String.format("phi = %.1f", Math.toDegrees(phi_r))); final long[] center = new long[] {size_x / 2, size_y / 2}; final long[] radiuses = new long[] {max_radius, max_radius}; final EllipseNeighborhood<UnsignedByteType> disc = new EllipseNeighborhood<UnsignedByteType>(img, center, radiuses); final EllipseCursor<UnsignedByteType> sc = disc.cursor(); double r2, phi, term; double cosphi, sinphi; while (sc.hasNext()) { sc.fwd(); r2 = sc.getDistanceSquared(); phi = sc.getPhi(); cosphi = Math.cos(phi - phi_r); sinphi = Math.sin(phi - phi_r); term = r2 * cosphi * cosphi / a / a + r2 * sinphi * sinphi / b / b; if (term <= 1) sc.get().set(on); } final long end = System.currentTimeMillis(); System.out.println("Ellipse creation done in " + (end - start) + " ms."); System.out.println(); ij.ImageJ.main(args); ImageJFunctions.show(imgplus); start = System.currentTimeMillis(); final Spot spot = new Spot(center[0], center[1], 0d, max_radius, -1d); final SpotMorphologyAnalyzer<UnsignedByteType> bm = new SpotMorphologyAnalyzer<UnsignedByteType>(imgplus, null); bm.process(spot); System.out.println("Blob morphology analyzed in " + (end - start) + " ms."); double phiv, thetav, lv; for (int j = 0; j < 2; j++) { lv = spot.getFeature(featurelist_sa[j]); phiv = spot.getFeature(featurelist_phi[j]); thetav = spot.getFeature(featurelist_theta[j]); System.out.println( String.format( "For axis of semi-length %.1f, orientation is phi = %.1f°, theta = %.1f°", lv, Math.toDegrees(phiv), Math.toDegrees(thetav))); } System.out.println(spot.echo()); // TEST 3D case /* * * // Parameters int size_x = 200; int size_y = 200; int size_z = 200; * * double a = 5.5f; double b = 4.9f; double c = 5; double theta_r = * (double) Math.toRadians(0); // I am unable to have it working for * theta_r != 0 double phi_r = (double) Math.toRadians(45); * * double max_radius = Math.max(a, Math.max(b, c)); double[] calibration * = new double[] {1, 1, 1}; * * // Create blank image Image<UnsignedByteType> img = new * ImageFactory<UnsignedByteType>( new UnsignedByteType(), new * ArrayContainerFactory() ).createImage(new int[] {200, 200, 200}); * final byte on = (byte) 255; * * // Create an ellipse long start = System.currentTimeMillis(); * System.out.println(String.format( * "Creating an ellipse with a = %.1f, b = %.1f, c = %.1f", a, b, c)); * System.out.println(String.format("phi = %.1f and theta = %.1f", * Math.toDegrees(phi_r), Math.toDegrees(theta_r))); double[] center = * new double[] { size_x/2, size_y/2, size_z/2 }; * SphereCursor<UnsignedByteType> sc = new * SphereCursor<UnsignedByteType>(img, center, max_radius, calibration); * double r2, theta, phi, term; double cosphi, sinphi, costheta, * sintheta; while (sc.hasNext()) { sc.fwd(); r2 = * sc.getDistanceSquared(); phi = sc.getPhi(); theta = sc.getTheta(); * cosphi = Math.cos(phi-phi_r); sinphi = Math.sin(phi-phi_r); costheta * = Math.cos(theta-theta_r); sintheta = Math.sin(theta-theta_r); term = * r2*cosphi*cosphi*sintheta*sintheta/a/a + * r2*sinphi*sinphi*sintheta*sintheta/b/b + r2*costheta*costheta/c/c; if * (term <= 1) sc.getType().set(on); } sc.close(); long end = * System.currentTimeMillis(); * System.out.println("Ellipse creation done in " + (end-start) + * " ms."); System.out.println(); * * ij.ImageJ.main(args); img.getDisplay().setMinMax(); * ImageJFunctions.copyToImagePlus(img).show(); * * start = System.currentTimeMillis(); BlobMorphology<UnsignedByteType> * bm = new BlobMorphology<UnsignedByteType>(img, calibration); SpotImp * spot = new SpotImp(center); spot.putFeature(Feature.RADIUS, * max_radius); bm.process(spot); end = System.currentTimeMillis(); * System.out.println("Blob morphology analyzed in " + (end-start) + * " ms."); double phiv, thetav, lv; for (int j = 0; j < 3; j++) { lv = * spot.getFeature(featurelist_sa[j]); phiv = * spot.getFeature(featurelist_phi[j]); thetav = * spot.getFeature(featurelist_theta[j]); * System.out.println(String.format( * "For axis of semi-length %.1f, orientation is phi = %.1f°, theta = %.1f°" * , lv, Math.toDegrees(phiv), Math.toDegrees(thetav))); } * System.out.println(spot.echo()); */ }
/** * Create a new imgage with using the current settings. * * @return the new image */ @SuppressWarnings("unchecked") public final <T extends NativeType<T> & RealType<T>> ImgPlus<T> nextImage() { // Set up new utils m_dimList = new ArrayList<Long>(); m_axisList = new ArrayList<AxisType>(); ImgFactoryTypes facType; // select a factory if (m_factory == null) { m_factory = ImgFactoryTypes.values()[randomBoundedInt(ImgFactoryTypes.values().length - 2)]; } if (m_randomFactory) { facType = ImgFactoryTypes.values()[randomBoundedInt(ImgFactoryTypes.values().length - 2)]; } else { facType = m_factory; } final ImgFactory<T> imgFac = ImgFactoryTypes.getImgFactory(facType); // process all dimensions processDimension(m_minSizeX, m_sizeX, "X"); processDimension(m_minSizeY, m_sizeY, "Y"); processDimension(m_minSizeZ, m_sizeZ, "Z"); processDimension(m_minSizeChannel, m_sizeChannel, "Channel"); processDimension(m_minSizeT, m_sizeT, "Time"); final long[] dims = new long[m_dimList.size()]; for (int d = 0; d < m_dimList.size(); d++) { dims[d] = m_dimList.get(d); } // Type of img is selected NativeTypes type; if (m_type == null) { m_type = NativeTypes.values()[randomBoundedInt(NativeTypes.values().length - 1)]; } if (m_randomType) { type = NativeTypes.values()[randomBoundedInt(NativeTypes.values().length - 1)]; } else { type = m_type; } // create the actual image final T val = (T) NativeTypes.getTypeInstance(type); final Img<T> img = imgFac.create(dims, val); // fill the image final Cursor<T> cursor = img.cursor(); while (cursor.hasNext()) { cursor.fwd(); double result; if (m_randomFill) { double sign = 1; if (val.getMinValue() < 0) { if (Math.random() > 0.5) { // ~50% negative sign = -1; } } if (type.equals(NativeTypes.DOUBLETYPE) || type.equals(NativeTypes.FLOATTYPE)) { // random value between -1 and 1 result = Math.random() * sign; } else { // random value in type range result = Math.random() * val.getMaxValue() * sign; } } else { result = m_value; } cursor.get().setReal(result); } final ImgPlus<T> imgPlus = new ImgPlus<T>(ImgView.wrap(img, imgFac)); int d = 0; for (final AxisType a : m_axisList) { imgPlus.setAxis(new DefaultLinearAxis(a), d++); } return imgPlus; }
@Override protected UnaryOutputOperation<ImgPlus<T>, ImgPlus<V>> op(final ImgPlus<T> vin) { final V outType = getOutType(vin.firstElement().createVariable()); return getSlidingOperation(vin, outType); }
/** * @param img * @param processorFactory * @param converter * @return wrapped {@link ImagePlus} */ @SuppressWarnings({"unchecked", "rawtypes"}) public static final <T extends RealType<T>> ImagePlus wrap( final ImgPlus<T> img, final ImageProcessorFactory processorFactory, final Converter<T, FloatType> converter) { // we always want to have 5 dimensions final RandomAccessibleInterval permuted = extendAndPermute(img); final int width = (int) permuted.dimension(0); final int height = (int) permuted.dimension(1); final ImagePlus r = new ImagePlus(); final ImageStack is = new ImageStack(width, height); final RandomAccessibleInterval<T> access = img.iterationOrder().equals(((IterableRealInterval<?>) permuted).iterationOrder()) ? img : permuted; final IntervalIterator ii = createIntervalIterator(access); final long[] min = new long[access.numDimensions()]; final long[] max = new long[access.numDimensions()]; max[0] = permuted.max(0); max[1] = permuted.max(1); // number of planes = num tasks int numSlices = 1; for (int d = 2; d < access.numDimensions(); d++) { numSlices *= access.dimension(d); } // parallelization final ImageProcessor[] slices = new ImageProcessor[numSlices]; final ExecutorService service = new ThreadPoolExecutorService( KNIMEConstants.GLOBAL_THREAD_POOL.createSubPool(KNIPConstants.THREADS_PER_NODE)); final ArrayList<Future<Void>> futures = new ArrayList<Future<Void>>(); final T inType = img.firstElement(); int i = 0; while (ii.hasNext()) { ii.fwd(); for (int d = 2; d < ii.numDimensions(); d++) { min[d] = ii.getIntPosition(d); max[d] = min[d]; } final int proxy = i++; futures.add( service.submit( new Callable<Void>() { final FinalInterval tmp = new FinalInterval(min, max); @Override public Void call() throws Exception { final Cursor<T> cursor = Views.iterable(Views.interval(access, tmp)).cursor(); final ImageProcessor ip = processorFactory.createProcessor(width, height, inType); final FloatType outProxy = new FloatType(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { converter.convert(cursor.next(), outProxy); ip.setf(x, y, outProxy.get()); } } slices[proxy] = ip; return null; } })); } for (final Future<Void> f : futures) { try { f.get(); } catch (final InterruptedException e) { e.printStackTrace(); } catch (final ExecutionException e) { e.printStackTrace(); } } // add slices to stack for (ImageProcessor slice : slices) { is.addSlice("", slice); } // set calibration final double[] newCalibration = getNewCalibration(img); Calibration cal = new Calibration(); cal.pixelWidth = newCalibration[0]; cal.pixelHeight = newCalibration[1]; cal.pixelDepth = newCalibration[3]; r.setCalibration(cal); r.setStack( is, (int) permuted.dimension(2), (int) permuted.dimension(3), (int) permuted.dimension(4)); r.setTitle(img.getName()); return r; }
/** * Wraps an {@link Img} using default IJ1Converter. * * @param img to be wrapped * @return wrapped {@link ImagePlus} */ public static final <T extends RealType<T>> ImagePlus wrap(final ImgPlus<T> img) { return wrap( img, new DefaultProcessorFactory(), new DefaultImgToIJ1Converter<T>(img.firstElement())); }