mpicbg.models.NoninvertibleModelException Java Examples

The following examples show how to use mpicbg.models.NoninvertibleModelException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Fusion.java    From Stitching with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void run() {

	// get chunk of pixels to process
	final Chunk myChunk = threadChunks.get(threadNumber);
	loopOffset = (int) myChunk.getStartPosition();
	loopSize = (int) myChunk.getLoopSize();

	try {
		// Process each tile index assigned to this thread
		// For each position in this tile, fuse its pixels across the
		// appropriate images
		// NB: recursion is necessary because there are an arbitrary
		// number of dimensions in the tile
		processTile(currentTile[0], 0, myFusion, transform, in, out, inPos,
			threadNumber, count, lastDraw, fusionImp[0]);
	}
	catch (NoninvertibleModelException e) {
		Log.error("Cannot invert model, qutting.");
		return;
	}

}
 
Example #2
Source File: Distortion_Correction.java    From TrakEM2 with GNU General Public License v3.0 6 votes vote down vote up
ImageProcessor applyTransformToImageInverse(
		final AbstractAffineModel2D< ? > a, final ImageProcessor ip){
	final ImageProcessor newIp = ip.duplicate();
	newIp.max(0.0);

	for (int x=0; x<ip.getWidth(); x++){
		for (int y=0; y<ip.getHeight(); y++){
			final double[] position = new double[]{x,y};
			//				float[] newPosition = a.apply(position);
			double[] newPosition = new double[]{0,0};
			try
			{
				newPosition = a.applyInverse(position);
			}
			catch ( final NoninvertibleModelException e ) {}

			final int xn = (int) newPosition[0];
			final int yn = (int) newPosition[1];

			if ( (xn >= 0) && (yn >= 0) && (xn < ip.getWidth()) && (yn < ip.getHeight()))
				newIp.set(xn,yn,ip.get(x,y));

		}
	}
	return newIp;
}
 
Example #3
Source File: Patch.java    From TrakEM2 with GNU General Public License v3.0 6 votes vote down vote up
/**
 * @see Patch#toPixelCoordinate(double, double)
 * @param world_x The X of the world coordinate (in pixels, uncalibrated)
 * @param world_y The Y of the world coordinate (in pixels, uncalibrated)
 * @param aff The {@link AffineTransform} of the {@link Patch}.
 * @param ct The {@link CoordinateTransform} of the {@link Patch}, if any (can be null).
 * @param meshResolution The precision demanded for approximating a transform with a {@link TransformMesh}.
 * @param o_width The width of the image underlying the {@link Patch}.
 * @param o_height The height of the image underlying the {@link Patch}.
 * @return A {@code double[]} array with the x,y values.
 * @throws NoninvertibleTransformException
 */
static public final double[] toPixelCoordinate(final double world_x, final double world_y,
		final AffineTransform aff, final CoordinateTransform ct,
		final int meshResolution, final int o_width, final int o_height) throws NoninvertibleTransformException {
	// Inverse the affine
	final double[] d = new double[]{world_x, world_y};
	aff.inverseTransform(d, 0, d, 0, 1);
	// Inverse the coordinate transform
	if (null != ct) {
		final double[] f = new double[]{d[0], d[1]};
		final mpicbg.models.InvertibleCoordinateTransform t =
			mpicbg.models.InvertibleCoordinateTransform.class.isAssignableFrom(ct.getClass()) ?
				(mpicbg.models.InvertibleCoordinateTransform) ct
				: new mpicbg.trakem2.transform.TransformMesh(ct, meshResolution, o_width, o_height);
			try { t.applyInverseInPlace(f); } catch ( final NoninvertibleModelException e ) {}
			d[0] = f[0];
			d[1] = f[1];
	}
	return d;
}
 
Example #4
Source File: ResidualCalculator.java    From render with GNU General Public License v2.0 6 votes vote down vote up
public static List<PointMatch> convertMatchesToLocal(final List<PointMatch> worldMatchList,
                                               final TileSpec pMatchTileSpec,
                                               final TileSpec qMatchTileSpec) {

    final List<PointMatch> localMatchList = new ArrayList<>(worldMatchList.size());
    Point pPoint;
    Point qPoint;
    for (final PointMatch worldMatch : worldMatchList) {
        try {
            pPoint = getLocalPoint(worldMatch.getP1(), pMatchTileSpec);
            qPoint = getLocalPoint(worldMatch.getP2(), qMatchTileSpec);
            localMatchList.add(new PointMatch(pPoint, qPoint));
        } catch (final NoninvertibleModelException e) {
            LOG.warn("skipping match", e);
        }
    }
    return localMatchList;
}
 
Example #5
Source File: TileSpec.java    From render with GNU General Public License v2.0 6 votes vote down vote up
/**
 * @param  x  world x coordinate to inversely transform into local coordinate.
 * @param  y  world y coordinate to inversely transform into local coordinate.
 *
 * @return local coordinates (x, y, z) for the specified world coordinates.
 *
 * @throws IllegalStateException
 *   if width or height have not been defined for this tile.
 *
 * @throws NoninvertibleModelException
 *   if this tile's transforms cannot be inverted for the specified point.
 */
public double[] getLocalCoordinates(final double x, final double y, final double meshCellSize)
        throws IllegalStateException, NoninvertibleModelException {

    final double[] localCoordinates;
    final double[] l = new double[] {x, y};
    if (hasTransforms()) {
        final CoordinateTransformMesh mesh = getCoordinateTransformMesh(meshCellSize);
        mesh.applyInverseInPlace(l);
    }

    if (z == null) {
        localCoordinates = l;
    } else {
        localCoordinates = new double[]{l[0], l[1], z};
    }

    return localCoordinates;
}
 
Example #6
Source File: MontageOutlierDiagnosticsClient.java    From render with GNU General Public License v2.0 5 votes vote down vote up
private Point2D.Double getPoint(final TileSpec normalizedTileSpec,
                                final double matchX,
                                final double matchY,
                                final TileSpec tileSpec)
        throws NoninvertibleModelException {
    final double[] local = normalizedTileSpec.getLocalCoordinates(matchX, matchY,
                                                                  normalizedTileSpec.getMeshCellSize());
    final double[] world = tileSpec.getWorldCoordinates(local[0], local[1]);
    return new Point2D.Double(world[0], world[1]);
}
 
Example #7
Source File: RenderTransformMesh.java    From render with GNU General Public License v2.0 5 votes vote down vote up
@Override
public double[] applyInverse(final double[] location) throws NoninvertibleModelException {
    assert location.length == 2 : "2d transform meshs can be applied to 2d points only.";

    final double[] transformed = location.clone();
    applyInverseInPlace(transformed);
    return transformed;
}
 
Example #8
Source File: RenderTransformMesh.java    From render with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void applyInverseInPlace(final double[] location) throws NoninvertibleModelException {
    assert location.length == 2 : "2d transform meshs can be applied to 2d points only.";

    for (final Pair<AffineModel2D, double[][]> apq : av) {
        if (isInTargetTriangle(apq.b, location)) {
            apq.a.applyInPlace(location);
            return;
        }
    }
    throw new NoninvertibleModelException("Noninvertible location ( " + location[0] + ", " + location[1] + " )");
}
 
Example #9
Source File: ResidualCalculator.java    From render with GNU General Public License v2.0 5 votes vote down vote up
private static Point getLocalPoint(final Point worldPoint,
                                   final TileSpec tileSpec)
        throws NoninvertibleModelException {
    final double[] world = worldPoint.getL();
    final double[] local = tileSpec.getLocalCoordinates(world[0], world[1], tileSpec.getMeshCellSize());
    return new Point(local);
}
 
Example #10
Source File: LaPlaceFunctions.java    From SPIM_Registration with GNU General Public License v2.0 5 votes vote down vote up
final static public void invert( double[] a ) throws NoninvertibleModelException
{
	assert a.length == 9 : "Matrix3x3 supports 3x3 double[][] only.";
	
	final double det = det( a );
	if ( det == 0 ) throw new NoninvertibleModelException( "Matrix not invertible." );
	
	final double i00 = ( a[ 4 ] * a[ 8 ] - a[ 5 ] * a[ 7 ] ) / det;
	final double i01 = ( a[ 2 ] * a[ 7 ] - a[ 1 ] * a[ 8 ] ) / det;
	final double i02 = ( a[ 1 ] * a[ 5 ] - a[ 2 ] * a[ 4 ] ) / det;
	
	final double i10 = ( a[ 5 ] * a[ 6 ] - a[ 3 ] * a[ 8 ] ) / det;
	final double i11 = ( a[ 0 ] * a[ 8 ] - a[ 2 ] * a[ 6 ] ) / det;
	final double i12 = ( a[ 2 ] * a[ 3 ] - a[ 0 ] * a[ 5 ] ) / det;
	
	final double i20 = ( a[ 3 ] * a[ 7 ] - a[ 4 ] * a[ 6 ] ) / det;
	final double i21 = ( a[ 1 ] * a[ 6 ] - a[ 0 ] * a[ 7 ] ) / det;
	final double i22 = ( a[ 0 ] * a[ 4 ] - a[ 1 ] * a[ 3 ] ) / det;
	
	a[ 0 ] = i00;
	a[ 1 ] = i01;
	a[ 2 ] = i02;

	a[ 3 ] = i10;
	a[ 4 ] = i11;
	a[ 5 ] = i12;

	a[ 6 ] = i20;
	a[ 7 ] = i21;
	a[ 8 ] = i22;
}
 
Example #11
Source File: Java3d.java    From SPIM_Registration with GNU General Public License v2.0 5 votes vote down vote up
final public static void applyInverseInPlace( final AbstractAffineModel3D<?> m, final Point3d p ) throws NoninvertibleModelException
{
	final double[] tmp = new double[ 3 ];
	
	tmp[ 0 ] = p.x;
	tmp[ 1 ] = p.y;
	tmp[ 2 ] = p.z;
	
	m.applyInverseInPlace( tmp );
	
	p.x = tmp[ 0 ];
	p.y = tmp[ 1 ];
	p.z = tmp[ 2 ];
}
 
Example #12
Source File: Java3d.java    From SPIM_Registration with GNU General Public License v2.0 5 votes vote down vote up
final public static void applyInverseInPlace( final AbstractAffineModel3D<?> m, final Point3d p, final double[] tmp ) throws NoninvertibleModelException
{
	tmp[ 0 ] = p.x;
	tmp[ 1 ] = p.y;
	tmp[ 2 ] = p.z;
	
	m.applyInverseInPlace( tmp );
	
	p.x = tmp[ 0 ];
	p.y = tmp[ 1 ];
	p.z = tmp[ 2 ];
}
 
Example #13
Source File: Fusion.java    From Stitching with GNU General Public License v2.0 5 votes vote down vote up
/**
	 * Intermediate helper method to delegate to
	 * {@link #processTile(ClassifiedRegion, int[], int, PixelFusion, ArrayList, ArrayList, LocalizableByDimCursor, float[], int[], int, int[], long[], ImagePlus)}
	 */
private void processTile(ClassifiedRegion r, int depth,
	PixelFusion myFusion, ArrayList<InvertibleBoundable> transform,
	ArrayList<RealRandomAccess<? extends RealType<?>>> in,
	RandomAccess<T> out, double[][] inPos,
	int threadNumber, int[] count, long[] lastDraw, ImagePlus fusionImp)
	throws NoninvertibleModelException
{
	processTile(r, r.classArray(), depth, myFusion, transform, in, out,
		inPos, threadNumber, count, lastDraw, fusionImp);
}
 
Example #14
Source File: Blending.java    From TrakEM2 with GNU General Public License v3.0 5 votes vote down vote up
/** Returns true if fo[0,1] x,y world coords intersect the affine and potentially coordinate transformed pixels of the other Patch. */
static private double intersects(final double[] fo, final Patch other, final TransformMesh mesh) {
	// First inverse affine transform
	final AffineTransform at = other.getAffineTransform();
	final Point2D.Double po = new Point2D.Double(fo[0], fo[1]);
	final int o_width = other.getOWidth();
	final int o_height = other.getOHeight();
	try {
		at.inverseTransform(po, po);
	} catch (final NoninvertibleTransformException nite) {
		return -1;
	}
	if (null == mesh) {
		if (po.x >= 0 && po.x < o_width
		 && po.y >= 0 && po.y < o_height) {
			return computeWeight(po.x, po.y, o_width, o_height);
		 } else {
			 return -1;
		 }
	}
	// Then inverse the coordinate transform
	try {
		fo[0] = po.x;
		fo[1] = po.y;
		mesh.applyInverseInPlace(fo);
		return computeWeight(fo[0], fo[1], o_width, o_height);
	} catch (final NoninvertibleModelException nime) {
		// outside boundaries
		return -1;
	}
}
 
Example #15
Source File: AlignTask.java    From TrakEM2 with GNU General Public License v3.0 5 votes vote down vote up
@Override
public final void applyInPlace(final double[] p) {
	try {
		ict.applyInverseInPlace(p);
	} catch (final NoninvertibleModelException e) {
		Utils.log2("Point outside mesh: " + p[0] + ", " + p[1]);
	}
}
 
Example #16
Source File: TileCoordinates.java    From render with GNU General Public License v2.0 4 votes vote down vote up
/**
 * @param  tileSpecList  list of tiles that contain the specified point
 *                       (order of list is assumed to be the same order used for rendering).
 *
 * @param  x             x coordinate.
 * @param  y             y coordinate.
 *
 * @return a local {@link TileCoordinates} instance with the inverse of the specified world point.
 *
 * @throws IllegalStateException
 *   if the specified point cannot be inverted for any of the specified tiles.
 */
public static List<TileCoordinates> getLocalCoordinates(
        final List<TileSpec> tileSpecList,
        final double x,
        final double y)
        throws IllegalStateException {


    final List<TileCoordinates> tileCoordinatesList = new ArrayList<>();
    List<String> nonInvertibleTileIds = null;
    double[] local;
    TileCoordinates tileCoordinates;
    for (final TileSpec tileSpec : tileSpecList) {
        try {
            local = tileSpec.getLocalCoordinates(x, y, tileSpec.getMeshCellSize());
            tileCoordinates = buildLocalInstance(tileSpec.getTileId(), local);
            tileCoordinatesList.add(tileCoordinates);
        } catch (final NoninvertibleModelException e) {
            if (nonInvertibleTileIds == null) {
                nonInvertibleTileIds = new ArrayList<>();
            }
            nonInvertibleTileIds.add(tileSpec.getTileId());
        }
    }

    final int numberOfInvertibleCoordinates = tileCoordinatesList.size();
    if (numberOfInvertibleCoordinates == 0) {
        throw new IllegalStateException("world coordinate (" + x + ", " + y + ") found in tile id(s) " +
                                        nonInvertibleTileIds + " cannot be inverted");
    } else {
        // Tiles are rendered in same order as specified tileSpecList.
        // Consequently for overlapping regions, the last tile will be the visible one
        // since it is rendered after or "on top of" the previous tile(s).
        final TileCoordinates lastTileCoordinates = tileCoordinatesList.get(numberOfInvertibleCoordinates - 1);
        lastTileCoordinates.setVisible(true);
    }

    if (nonInvertibleTileIds != null) {
        LOG.info("getLocalCoordinates: skipped inverse transform of ({}, {}) for non-invertible tile id(s) {}, used tile id {} instead",
                 x, y, nonInvertibleTileIds, tileCoordinatesList.get(0).getTileId());
    }

    return tileCoordinatesList;
}
 
Example #17
Source File: Fusion.java    From Stitching with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Helper method to fuse all the positions of a given
 * {@link ClassifiedRegion}. Since we do not know the dimensionality of the
 * region, we recurse over each position of each dimension. The tail step of
 * each descent iterates over all the images (classes) of the given region,
 * fusing the pixel values at the current position of each associated image.
 * This final value is then set in the output.
 */
private void processTile(ClassifiedRegion r, int[] images, int depth,
	PixelFusion myFusion, ArrayList<InvertibleBoundable> transform,
	ArrayList<RealRandomAccess<? extends RealType<?>>> in,
	RandomAccess<T> out, double[][] inPos,
	int threadNumber, int[] count, long[] lastDraw, ImagePlus fusionImp)
	throws NoninvertibleModelException
{
	// NB: there are two process tile methods, one for in-memory fusion
	// and one for writing to disk. They are slightly different, but
	// if one is updated the other should be as well!
	if (depth < r.size()) {
		Interval d = r.get(depth);

		// The intervals of the given region define the bounds of
		// iteration
		// So we are recursively defining a nested iteration order to
		// cover each position of the region
		int start = d.min();
		int end = d.max();

		// If this is the dimension being split up for multi-threading we
		// need to update the iteration bounds.
		if (depth == loopDim[0]) {
			start += loopOffset;
			end = start + loopSize - 1;
		}

		out.setPosition(start, depth);

		// NB: can't make this loop inclusive since we don't want the out.fwd
		// call to go out of bounds, and we can't setPosition (-1) or we
		// get AIOOB exceptions. So we loop 1 time less than desired, then
		// do a straight read after the loop.
		for (int i = start; i < end; i++) {
			// Recurse to the next depth (dimension)
			processTile(r, images, depth + 1, myFusion, transform, in, out,
				inPos, threadNumber, count, lastDraw, fusionImp);
			// move forward
			out.fwd(depth);
		}

		// Need to read the final position.
		processTile(r, images, depth + 1, myFusion, transform, in, out,
			inPos, threadNumber, count, lastDraw, fusionImp);
		return;
	}

	// compute fusion for this position
	myFusion.clear();

	// Loop over the images in this region
	for (int d = 0; d < r.size(); d++) {
		final double value = out.getDoublePosition(d) + offset[d];

		for (int index = 0; index < images.length; index++) {
			// Get the positions for the current image
			inPos[images[index]][d] = value;
		}
	}

	// Get the value at each input position
	for (int index = 0; index < images.length; index++) {
		final int image = images[index];
		// Transform to get input position
		transform.get(image).applyInverseInPlace(inPos[image]);
		in.get(image).setPosition(inPos[image]);
		// fuse
		myFusion.addValue(in.get(image).get().getRealFloat(), image, inPos[image]);
	}

	// set value
	out.get().setReal(myFusion.getValue());

	// Display progress if on thread 0
	if (threadNumber == 0) {
		count[0]++;
		// just every 10000'th pixel
		if (count[0] % 10000 == 0) {
			lastDraw[0] = drawFusion(lastDraw[0], fusionImp);
			IJ.showProgress(count[0] / positionsPerThread);
		}
	}
}
 
Example #18
Source File: ResidualCalculatorTest.java    From render with GNU General Public License v2.0 4 votes vote down vote up
@Test
public void testRun()
        throws NoninvertibleModelException {

    final String pMatchJson =
            "{\n" +
            "\"tileId\": \"151217110113032085.535.0\",\n" +
            "\"z\": 535, \"minX\": 8, \"minY\": 32, \"maxX\": 2671, \"maxY\": 2322,\n" +
            "\"width\": 2560, \"height\": 2160,\n" +
            "\"transforms\": {\n" +
            "\"type\": \"list\",\n" +
            "\"specList\": []}}";

    final TileSpec pMatchTileSpec = TileSpec.fromJson(pMatchJson);

    final String pAlignedJson =
            "{\n" +
            "\"tileId\": \"151217110113032085.535.0\",\n" +
            "\"z\": 535, \"minX\": 33114, \"minY\": 32638, \"maxX\": 35784, \"maxY\": 34945,\n" +
            "\"width\": 2560, \"height\": 2160,\n" +
            "\"transforms\": {\n" +
            "\"type\": \"list\",\n" +
            "\"specList\": [\n" +
            "{\"type\": \"leaf\", \"className\": \"mpicbg.trakem2.transform.AffineModel2D\",\n" +
            "\"dataString\": \"-0.999639554083 -0.005504829254 0.004191949996 -1.001725487903 35784.416966470395 34978.608372966301\"\n" +
            "}]}}";

    final TileSpec pAlignedTileSpec = TileSpec.fromJson(pAlignedJson);

    final String qMatchJson =
            "{\n" +
            "\"tileId\": \"151217110113033085.535.0\",\n" +
            "\"z\": 535, \"minX\": 8, \"minY\": 32, \"maxX\": 2671, \"maxY\": 2322," +
            "\"width\": 2560, \"height\": 2160,\n" +
            "\"transforms\": {\n" +
            "\"type\": \"list\",\n" +
            "\"specList\": []}}";

    final TileSpec qMatchTileSpec = TileSpec.fromJson(qMatchJson);

    final String qAlignedJson =
            "{\n" +
            "\"tileId\": \"151217110113033085.535.0\",\n" +
            "\"z\": 535, \"minX\": 31120, \"minY\": 32599, \"maxX\": 33799, \"maxY\": 34904,\n" +
            "\"width\": 2560, \"height\": 2160,\n" +
            "\"transforms\": {\n" +
            "\"type\": \"list\",\n" +
            "\"specList\": [\n" +
            "{\"type\": \"leaf\", \"className\": \"mpicbg.trakem2.transform.AffineModel2D\",\n" +
            "\"dataString\": \"-1.001433887474 -0.005109778257 0.005917430007 -1.000864015786 33794.433334533365 34936.117736529850\"\n" +
            "}]}}";

    final TileSpec qAlignedTileSpec = TileSpec.fromJson(qAlignedJson);

    final String matchJson =
            "{\n" +
            "\"pGroupId\": \"535.0\",\n" +
            "\"pId\": \"151217110113032085.535.0\",\n" +
            "\"qGroupId\": \"535.0\",\n" +
            "\"qId\": \"151217110113033085.535.0\",\n" +
            "\"matches\" : {\n" +
            "    \"p\" : [ [ 2560.1941965996325, 2413.9112942072984, 2251.435464934693, 2329.8600573814765, 2211.092952452758, 2555.4460121944217, 2250.329455385571, 2398.068442078769, 2395.4977683697925, 2391.1115953227527, 2252.883919346284, 2194.5220204070743, 2563.853227802642 ], [ 565.3970791378985, 411.3584295909637, 2069.6431122079316, 1818.9130883125376, 1168.8230563077875, 476.4527422135635, 2052.155563818892, 2029.7708176014512, 1809.7939391200136, 1801.614570450891, 1801.293083285957, 1800.5741896077263, 601.4353336995042 ] ],\n" +
            "    \"q\" : [ [ 566.8473967742441, 423.377389666387, 258.00346745927595, 335.709934133493, 217.25216114449387, 562.6997540981155, 258.0194971631647, 403.7424335497306, 402.6878793541385, 398.54554557954407, 261.10426183584826, 201.15684802206715, 569.5727620093525 ], [ 533.3904989216358, 377.137526111664, 2037.5048709254368, 1785.7718930116732, 1134.763306819837, 443.1958247188568, 2019.6823761456749, 1998.8216258172304, 1778.0862520400428, 1768.9313919357605, 1769.7979329469345, 1770.1668410990153, 568.6040573691449 ] ],\n" +
            "    \"w\" : [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ]\n" +
            "  }\n" +
            "}";

    final CanvasMatches canvasMatches = CanvasMatches.fromJson(matchJson);

    final StackId testStackId = new StackId("tester", "testProject", "testStack");
    final MatchCollectionId testCollectionId = new MatchCollectionId("tester", "testMatches");

    final ResidualCalculator.InputData inputData = new ResidualCalculator.InputData(pAlignedTileSpec.getTileId(),
                                                                                    qAlignedTileSpec.getTileId(),
                                                                                    testStackId,
                                                                                    testCollectionId,
                                                                                    true);

    final List<PointMatch> worldMatchList = canvasMatches.getMatches().createPointMatches();
    final List<PointMatch> localMatchList =
            ResidualCalculator.convertMatchesToLocal(worldMatchList, pMatchTileSpec, qMatchTileSpec);


    final ResidualCalculator residualCalculator = new ResidualCalculator();
    final ResidualCalculator.Result result = residualCalculator.run(testStackId,
                                                                    inputData,
                                                                    localMatchList,
                                                                    pAlignedTileSpec,
                                                                    qAlignedTileSpec);
    System.out.println(ResidualCalculator.Result.getHeader());
    System.out.println(result.toString());
}
 
Example #19
Source File: Layer.java    From TrakEM2 with GNU General Public License v3.0 4 votes vote down vote up
/** Transfer the world coordinate specified by {@code world_x},{@code world_y}
 * in pixels, to the local coordinate of the {@link Patch} immediately present under it.
 * @return null if no {@link Patch} is under the coordinate, else the {@link Coordinate} with the x, y, {@link Layer} and the {@link Patch}.
 * @throws NoninvertibleModelException 
 * @throws NoninvertibleTransformException 
 */
public Coordinate<Patch> toPatchCoordinate(final double world_x, final double world_y) throws NoninvertibleTransformException, NoninvertibleModelException {
	final Collection<Displayable> ps = find(Patch.class, world_x, world_y, true, false);
	Patch patch = null;
	if (ps.isEmpty()) {
		// No Patch under the point. Find the nearest Patch instead
		final Collection<Patch> patches = getAll(Patch.class);
		if (patches.isEmpty()) return null;
		double minSqDist = Double.MAX_VALUE;
		for (final Patch p : patches) {
			// Check if any of the 4 corners of the bounding box are beyond minSqDist
			final Rectangle b = p.getBoundingBox();
			final double d1 = Math.pow(b.x - world_x, 2) + Math.pow(b.y - world_y, 2),
			       d2 = Math.pow(b.x + b.width - world_x, 2) + Math.pow(b.y - world_y, 2),
			       d3 = Math.pow(b.x - world_x, 2) + Math.pow(b.y + b.height - world_y, 2),
			       d4 = Math.pow(b.x + b.width - world_x, 2) + Math.pow(b.y + b.height - world_y, 2),
			       d = Math.min(d1, Math.min(d2, Math.min(d3, d4)));
			if (d < minSqDist) {
				patch = p;
				minSqDist = d;
			}
			// If the Patch has a CoordinateTransform, find the closest perimeter point
			if (p.hasCoordinateTransform()) {
				for (final Polygon pol : M.getPolygons(p.getArea())) { // Area in world coordinates
					for (int i=0; i<pol.npoints; ++i) {
						final double sqDist = Math.pow(pol.xpoints[0] - world_x, 2) + Math.pow(pol.ypoints[1] - world_y, 2);
						if (sqDist < minSqDist) {
							minSqDist = sqDist;
							patch = p;
						}
					}
				}
			}
		}
	} else {
		patch = (Patch) ps.iterator().next();
	}

	final double[] point = patch.toPixelCoordinate(world_x, world_y);
	return new Coordinate<Patch>(point[0], point[1], patch.getLayer(), patch);
}
 
Example #20
Source File: AbstractAffineTile2D.java    From TrakEM2 with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Add a virtual {@linkplain PointMatch connection} between two
 * {@linkplain AbstractAffineTile2D Tiles}.  The
 * {@linkplain PointMatch connection} is placed in the center of the
 * intersection area of both tiles.
 *
 * TODO Not yet tested---Do we need these virtual connections?
 *
 * @param t
 */
final public void makeVirtualConnection( final AbstractAffineTile2D< ? > t )
{
	final Area a = new Area( patch.getPerimeter() );
	final Area b = new Area( t.patch.getPerimeter() );
	a.intersect( b );

	final double[] fa = new double[ 2 ];
	int i = 0;

	final double[] coords = new double[ 6 ];

	final PathIterator p = a.getPathIterator( null );
	while ( !p.isDone() )
	{
		p.currentSegment( coords );
		fa[ 0 ] += coords[ 0 ];
		fa[ 1 ] += coords[ 1 ];
		++i;
		p.next();
	}

	if ( i > 0 )
	{
		fa[ 0 ] /= i;
		fa[ 1 ] /= i;

		final double[] fb = fa. clone();
		try
		{
			model.applyInverseInPlace( fa );
			t.model.applyInverseInPlace( fb );
		}
		catch ( final NoninvertibleModelException e ) { return; }

		final Point pa = new Point( fa );
		final Point pb = new Point( fb );
		final PointMatch ma = new PointMatch( pa, pb, 0.1f );
		final PointMatch mb = new PointMatch( pb, pa, 0.1f );

		addVirtualMatch( ma );
		addConnectedTile( t );
		t.addVirtualMatch( mb );
		t.addConnectedTile( this );
	}
}
 
Example #21
Source File: OverlayFusion.java    From Stitching with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Fuse one slice/volume (one channel)
 * 
 * @param output - same the type of the ImagePlus input
 * @param input - FloatType, because of Interpolation that needs to be done
 * @param transform - the transformation
 */
protected static <T extends RealType<T>> void fuseChannel( final Img<T> output, final RealRandomAccessible<FloatType> input, final double[] offset, final InvertibleCoordinateTransform transform )
{
	final int dims = output.numDimensions();
	long imageSize = output.dimension( 0 );
	
	for ( int d = 1; d < output.numDimensions(); ++d )
		imageSize *= output.dimension( d );

	// run multithreaded
	final AtomicInteger ai = new AtomicInteger(0);					
       final Thread[] threads = SimpleMultiThreading.newThreads();

       final Vector<Chunk> threadChunks = SimpleMultiThreading.divideIntoChunks( imageSize, threads.length );
       
       for (int ithread = 0; ithread < threads.length; ++ithread)
           threads[ithread] = new Thread(new Runnable()
           {
               @Override
               public void run()
               {
               	// Thread ID
               	final int myNumber = ai.getAndIncrement();
       
               	// get chunk of pixels to process
               	final Chunk myChunk = threadChunks.get( myNumber );
               	final long startPos = myChunk.getStartPosition();
               	final long loopSize = myChunk.getLoopSize();
               	
           		final Cursor<T> out = output.localizingCursor();
           		final RealRandomAccess<FloatType> in = input.realRandomAccess();
           		
           		final double[] tmp = new double[ input.numDimensions() ];
           		
           		try 
           		{
               		// move to the starting position of the current thread
           			out.jumpFwd( startPos );
           			
               		// do as many pixels as wanted by this thread
                       for ( long j = 0; j < loopSize; ++j )
                       {
           				out.fwd();
           				
           				for ( int d = 0; d < dims; ++d )
           					tmp[ d ] = out.getDoublePosition( d ) + offset[ d ];
           				
           				transform.applyInverseInPlace( tmp );
           	
           				in.setPosition( tmp );
           				out.get().setReal( in.get().get() );
           			}
           		} 
           		catch (NoninvertibleModelException e) 
           		{
           			Log.error( "Cannot invert model, qutting." );
           			return;
           		}

               }
           });
       
       SimpleMultiThreading.startAndJoin( threads );
	
       /*
	final LocalizableCursor<T> out = output.createLocalizableCursor();
	final Interpolator<FloatType> in = input.createInterpolator( factory );
	
	final float[] tmp = new float[ input.getNumDimensions() ];
	
	try 
	{
		while ( out.hasNext() )
		{
			out.fwd();
			
			for ( int d = 0; d < dims; ++d )
				tmp[ d ] = out.getPosition( d ) + offset[ d ];
			
			transform.applyInverseInPlace( tmp );

			in.setPosition( tmp );			
			out.getType().setReal( in.getType().get() );
		}
	} 
	catch (NoninvertibleModelException e) 
	{
		Log.error( "Cannot invert model, qutting." );
		return;
	}
	*/
}