Example #1
0
 public boolean remove(boolean check) {
   if (check) {
     if (!Utils.check(
         "Really delete "
             + this.toString()
             + (null == al_children || 0 == al_children.size() ? "" : " and all its children?")))
       return false;
   }
   // remove the children, recursively
   if (null != al_children) {
     Object[] children = new Object[al_children.size()];
     al_children.toArray(
         children); // can't delete directly from the al_children because the child will call
                    // removeChild on its parent
     for (int i = 0; i < children.length; i++) {
       Object ob = children[i];
       if (ob instanceof DBObject) {
         if (!((DBObject) ob).remove(false)) {
           Utils.showMessage("Deletion incomplete, check database, for child: " + ob.toString());
           return false;
         }
       }
     }
   }
   // remove the Thing itself
   if (null != parent && !parent.removeChild(this)) {
     Utils.showMessage(
         "Deletion incomplete, check database, for parent of TemplateThing id=" + id);
     return false;
   }
   return removeFromDatabase();
 }
Example #2
0
  public final void exec(final List<Patch> patches, final Set<Patch> fixedPatches)
      throws Exception {
    /* make sure that passed patches are ok */
    if (patches.size() < 2) {
      Utils.log(
          "Elastic montage requires at least 2 patches to be montaged.  You passed me "
              + patches.size());
      return;
    }
    final Project project = patches.get(0).getProject();
    for (final Patch patch : patches) {
      if (patch.getProject() != project) {
        Utils.log(
            "Elastic montage requires all patches to be member of a single project.  You passed me patches from several projects.");
        return;
      }
    }
    for (final Patch patch : fixedPatches) {
      if (patch.getProject() != project) {
        Utils.log(
            "Elastic montage requires all fixed patches to be member of a single project.  You passed me fixed patches from several projects.");
        return;
      }
    }

    final Param param = setup();
    if (param == null) return;
    else exec(param, patches, fixedPatches);
  }
Example #3
0
 public boolean removeChild(TemplateThing child) {
   // check that it is contained here
   if (-1 == al_children.indexOf(child)) {
     Utils.log("TemplateThing.removeChild: child " + child + " not contained in parent " + this);
     return false;
   }
   al_children.remove(child);
   return true;
 }
Example #4
0
 @Override
 public ResultsTable measure(ResultsTable rt) {
   if (0 == al_items.size()) return rt;
   if (null == rt)
     rt =
         Utils.createResultsTable(
             "Dissector results", new String[] {"id", "tag", "x", "y", "z", "radius", "nameid"});
   for (final Item item : al_items) item.addResults(rt, layer_set.getCalibration(), getNameId());
   return rt;
 }
Example #5
0
 final void addResults(final ResultsTable rt, final Calibration cal, final double nameid) {
   for (int i = 0; i < n_points; i++) {
     final Layer la = layer_set.getLayer(p_layer[i]);
     if (null == layer) {
       Utils.log("Dissector.addResults: could not find layer with id " + p_layer[i]);
       continue;
     }
     final Point2D.Double po = M.transform(Dissector.this.at, p[0][i], p[1][i]);
     rt.incrementCounter();
     rt.addLabel("units", cal.getUnit());
     rt.addValue(0, Dissector.this.id);
     rt.addValue(1, tag);
     rt.addValue(2, po.x * cal.pixelWidth);
     rt.addValue(3, po.y * cal.pixelHeight);
     rt.addValue(4, la.getZ() * cal.pixelWidth); // layer Z is in pixels
     rt.addValue(5, radius * cal.pixelWidth);
     rt.addValue(6, nameid);
   }
 }
Example #6
0
 public boolean addChild(Thing child) {
   if (null == child) return false;
   if (null == al_children) al_children = new ArrayList<TemplateThing>();
   else {
     // check that no child is already of the same type as the new child
     for (final TemplateThing tc : al_children) {
       if (tc.type.equals(((TemplateThing) child).type)) {
         Utils.log2("TemplateThing.addChild: already have a child of type " + tc.type);
         // Utils.printCaller(this, 10);
         return false;
       }
     }
     // TODO should change to use a Map<String,TemplateThing>.
     // but then there wouldn't be a sequential order.
   }
   // Utils.log2("Added child of type " + ((TemplateThing)child).type);
   al_children.add((TemplateThing) child);
   child.setParent(this);
   return true;
 }
Example #7
0
 @Override
 public void exportXML(
     final StringBuilder sb_body, final String indent, final XMLOptions options) {
   sb_body.append(indent).append("<t2_dissector\n");
   final String in = indent + "\t";
   super.exportXML(sb_body, in, options);
   final String[] RGB = Utils.getHexRGBColor(color);
   sb_body
       .append(in)
       .append("style=\"fill:none;stroke-opacity:")
       .append(alpha)
       .append(";stroke:#")
       .append(RGB[0])
       .append(RGB[1])
       .append(RGB[2])
       .append(";stroke-width:1.0px;\"\n");
   sb_body.append(indent).append(">\n");
   for (final Item item : al_items) {
     item.exportXML(sb_body, in);
   }
   super.restXML(sb_body, in, options);
   sb_body.append(indent).append("</t2_dissector>\n");
 }
Example #8
0
  @SuppressWarnings("deprecation")
  public final void exec(
      final Param param, final List<Patch> patches, final Set<Patch> fixedPatches)
      throws Exception {
    /* free memory */
    patches.get(0).getProject().getLoader().releaseAll();

    /* create tiles and models for all patches */
    final ArrayList<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>();
    final ArrayList<AbstractAffineTile2D<?>> fixedTiles = new ArrayList<AbstractAffineTile2D<?>>();
    Align.tilesFromPatches(param.po, patches, fixedPatches, tiles, fixedTiles);

    if (!param.isAligned) {
      Align.alignTiles(param.po, tiles, fixedTiles, param.tilesAreInPlace, param.maxNumThreads);

      /* Apply the estimated affine transform to patches */
      for (final AbstractAffineTile2D<?> t : tiles)
        t.getPatch().setAffineTransform(t.createAffine());

      Display.update();
    }

    /* generate tile pairs for all by now overlapping tiles */
    final ArrayList<AbstractAffineTile2D<?>[]> tilePairs =
        new ArrayList<AbstractAffineTile2D<?>[]>();
    AbstractAffineTile2D.pairOverlappingTiles(tiles, tilePairs);

    /* check if there was any pair */
    if (tilePairs.size() == 0) {
      Utils.log("Elastic montage could not find any overlapping patches after pre-montaging.");
      return;
    }

    Utils.log(tilePairs.size() + " pairs of patches will be block-matched...");

    /* make pairwise global models local */
    final ArrayList<
            Triple<AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform>>
        pairs =
            new ArrayList<
                Triple<
                    AbstractAffineTile2D<?>,
                    AbstractAffineTile2D<?>,
                    InvertibleCoordinateTransform>>();

    /*
     * The following casting madness is necessary to get this code compiled
     * with Sun/Oracle Java 6 which otherwise generates an inconvertible
     * type exception.
     *
     * TODO Remove as soon as this bug is fixed in Sun/Oracle javac.
     */
    for (final AbstractAffineTile2D<?>[] pair : tilePairs) {
      final AbstractAffineModel2D<?> m;
      switch (param.po.desiredModelIndex) {
        case 0:
          final TranslationModel2D t =
              (TranslationModel2D) (Object) pair[1].getModel().createInverse();
          t.concatenate((TranslationModel2D) (Object) pair[0].getModel());
          m = t;
          break;
        case 1:
          final RigidModel2D r = (RigidModel2D) (Object) pair[1].getModel().createInverse();
          r.concatenate((RigidModel2D) (Object) pair[0].getModel());
          m = r;
          break;
        case 2:
          final SimilarityModel2D s =
              (SimilarityModel2D) (Object) pair[1].getModel().createInverse();
          s.concatenate((SimilarityModel2D) (Object) pair[0].getModel());
          m = s;
          break;
        case 3:
          final AffineModel2D a = (AffineModel2D) (Object) pair[1].getModel().createInverse();
          a.concatenate((AffineModel2D) (Object) pair[0].getModel());
          m = a;
          break;
        default:
          m = null;
      }
      pairs.add(
          new Triple<
              AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform>(
              pair[0], pair[1], m));
    }

    /* Elastic alignment */

    /* Initialization */
    final double springTriangleHeightTwice =
        2 * Math.sqrt(0.75 * param.springLengthSpringMesh * param.springLengthSpringMesh);

    final ArrayList<SpringMesh> meshes = new ArrayList<SpringMesh>(tiles.size());
    final HashMap<AbstractAffineTile2D<?>, SpringMesh> tileMeshMap =
        new HashMap<AbstractAffineTile2D<?>, SpringMesh>();
    for (final AbstractAffineTile2D<?> tile : tiles) {
      final double w = tile.getWidth();
      final double h = tile.getHeight();
      final int numX = Math.max(2, (int) Math.ceil(w / param.springLengthSpringMesh) + 1);
      final int numY = Math.max(2, (int) Math.ceil(h / springTriangleHeightTwice) + 1);
      final double wMesh = (numX - 1) * param.springLengthSpringMesh;
      final double hMesh = (numY - 1) * springTriangleHeightTwice;

      final SpringMesh mesh =
          new SpringMesh(
              numX,
              numY,
              wMesh,
              hMesh,
              param.stiffnessSpringMesh,
              param.maxStretchSpringMesh * param.bmScale,
              param.dampSpringMesh);
      meshes.add(mesh);
      tileMeshMap.put(tile, mesh);
    }

    //		final int blockRadius = Math.max( 32, Util.roundPos( param.springLengthSpringMesh / 2 ) );
    final int blockRadius = Math.max(Util.roundPos(16 / param.bmScale), param.bmBlockRadius);

    /** TODO set this something more than the largest error by the approximate model */
    final int searchRadius = param.bmSearchRadius;

    final AbstractModel<?> localSmoothnessFilterModel =
        mpicbg.trakem2.align.Util.createModel(param.bmLocalModelIndex);

    for (final Triple<
            AbstractAffineTile2D<?>, AbstractAffineTile2D<?>, InvertibleCoordinateTransform>
        pair : pairs) {
      final AbstractAffineTile2D<?> t1 = pair.a;
      final AbstractAffineTile2D<?> t2 = pair.b;

      final SpringMesh m1 = tileMeshMap.get(t1);
      final SpringMesh m2 = tileMeshMap.get(t2);

      final ArrayList<PointMatch> pm12 = new ArrayList<PointMatch>();
      final ArrayList<PointMatch> pm21 = new ArrayList<PointMatch>();

      final ArrayList<Vertex> v1 = m1.getVertices();
      final ArrayList<Vertex> v2 = m2.getVertices();

      final String patchName1 = patchName(t1.getPatch());
      final String patchName2 = patchName(t2.getPatch());

      final PatchImage pi1 = t1.getPatch().createTransformedImage();
      if (pi1 == null) {
        Utils.log("Patch `" + patchName1 + "' failed generating a transformed image.  Skipping...");
        continue;
      }
      final PatchImage pi2 = t2.getPatch().createTransformedImage();
      if (pi2 == null) {
        Utils.log("Patch `" + patchName2 + "' failed generating a transformed image.  Skipping...");
        continue;
      }

      final FloatProcessor fp1 = (FloatProcessor) pi1.target.convertToFloat();
      final ByteProcessor mask1 = pi1.getMask();
      final FloatProcessor fpMask1 = mask1 == null ? null : scaleByte(mask1);

      final FloatProcessor fp2 = (FloatProcessor) pi2.target.convertToFloat();
      final ByteProcessor mask2 = pi2.getMask();
      final FloatProcessor fpMask2 = mask2 == null ? null : scaleByte(mask2);

      if (!fixedTiles.contains(t1)) {
        BlockMatching.matchByMaximalPMCC(
            fp1,
            fp2,
            fpMask1,
            fpMask2,
            param.bmScale,
            pair.c,
            blockRadius,
            blockRadius,
            searchRadius,
            searchRadius,
            param.bmMinR,
            param.bmRodR,
            param.bmMaxCurvatureR,
            v1,
            pm12,
            new ErrorStatistic(1));

        if (param.bmUseLocalSmoothnessFilter) {
          Utils.log(
              "`"
                  + patchName1
                  + "' > `"
                  + patchName2
                  + "': found "
                  + pm12.size()
                  + " correspondence candidates.");
          localSmoothnessFilterModel.localSmoothnessFilter(
              pm12, pm12, param.bmLocalRegionSigma, param.bmMaxLocalEpsilon, param.bmMaxLocalTrust);
          Utils.log(
              "`"
                  + patchName1
                  + "' > `"
                  + patchName2
                  + "': "
                  + pm12.size()
                  + " candidates passed local smoothness filter.");
        } else {
          Utils.log(
              "`"
                  + patchName1
                  + "' > `"
                  + patchName2
                  + "': found "
                  + pm12.size()
                  + " correspondences.");
        }
      } else {
        Utils.log("Skipping fixed patch `" + patchName1 + "'.");
      }

      //			/* <visualisation> */
      //			//			final List< Point > s1 = new ArrayList< Point >();
      //			//			PointMatch.sourcePoints( pm12, s1 );
      //			//			final ImagePlus imp1 = new ImagePlus( i + " >", ip1 );
      //			//			imp1.show();
      //			//			imp1.setOverlay( BlockMatching.illustrateMatches( pm12 ), Color.yellow, null );
      //			//			imp1.setRoi( Util.pointsToPointRoi( s1 ) );
      //			//			imp1.updateAndDraw();
      //			/* </visualisation> */

      if (!fixedTiles.contains(t2)) {
        BlockMatching.matchByMaximalPMCC(
            fp2,
            fp1,
            fpMask2,
            fpMask1,
            param.bmScale,
            pair.c.createInverse(),
            blockRadius,
            blockRadius,
            searchRadius,
            searchRadius,
            param.bmMinR,
            param.bmRodR,
            param.bmMaxCurvatureR,
            v2,
            pm21,
            new ErrorStatistic(1));

        if (param.bmUseLocalSmoothnessFilter) {
          Utils.log(
              "`"
                  + patchName1
                  + "' < `"
                  + patchName2
                  + "': found "
                  + pm21.size()
                  + " correspondence candidates.");
          localSmoothnessFilterModel.localSmoothnessFilter(
              pm21, pm21, param.bmLocalRegionSigma, param.bmMaxLocalEpsilon, param.bmMaxLocalTrust);
          Utils.log(
              "`"
                  + patchName1
                  + "' < `"
                  + patchName2
                  + "': "
                  + pm21.size()
                  + " candidates passed local smoothness filter.");
        } else {
          Utils.log(
              "`"
                  + patchName1
                  + "' < `"
                  + patchName2
                  + "': found "
                  + pm21.size()
                  + " correspondences.");
        }
      } else {
        Utils.log("Skipping fixed patch `" + patchName2 + "'.");
      }

      /* <visualisation> */
      //			final List< Point > s2 = new ArrayList< Point >();
      //			PointMatch.sourcePoints( pm21, s2 );
      //			final ImagePlus imp2 = new ImagePlus( i + " <", ip2 );
      //			imp2.show();
      //			imp2.setOverlay( BlockMatching.illustrateMatches( pm21 ), Color.yellow, null );
      //			imp2.setRoi( Util.pointsToPointRoi( s2 ) );
      //			imp2.updateAndDraw();
      /* </visualisation> */

      for (final PointMatch pm : pm12) {
        final Vertex p1 = (Vertex) pm.getP1();
        final Vertex p2 = new Vertex(pm.getP2());
        p1.addSpring(p2, new Spring(0, 1.0f));
        m2.addPassiveVertex(p2);
      }

      for (final PointMatch pm : pm21) {
        final Vertex p1 = (Vertex) pm.getP1();
        final Vertex p2 = new Vertex(pm.getP2());
        p1.addSpring(p2, new Spring(0, 1.0f));
        m1.addPassiveVertex(p2);
      }
    }

    /* initialize */
    for (final Map.Entry<AbstractAffineTile2D<?>, SpringMesh> entry : tileMeshMap.entrySet())
      entry.getValue().init(entry.getKey().getModel());

    /* optimize the meshes */
    try {
      final long t0 = System.currentTimeMillis();
      IJ.log("Optimizing spring meshes...");

      if (param.useLegacyOptimizer) {
        Utils.log("  ...using legacy optimizer...");
        SpringMesh.optimizeMeshes2(
            meshes,
            param.po.maxEpsilon,
            param.maxIterationsSpringMesh,
            param.maxPlateauwidthSpringMesh,
            param.visualize);
      } else {
        SpringMesh.optimizeMeshes(
            meshes,
            param.po.maxEpsilon,
            param.maxIterationsSpringMesh,
            param.maxPlateauwidthSpringMesh,
            param.visualize);
      }
      IJ.log("Done optimizing spring meshes. Took " + (System.currentTimeMillis() - t0) + " ms");

    } catch (final NotEnoughDataPointsException e) {
      Utils.log("There were not enough data points to get the spring mesh optimizing.");
      e.printStackTrace();
      return;
    }

    /* apply */
    for (final Map.Entry<AbstractAffineTile2D<?>, SpringMesh> entry : tileMeshMap.entrySet()) {
      final AbstractAffineTile2D<?> tile = entry.getKey();
      if (!fixedTiles.contains(tile)) {
        final Patch patch = tile.getPatch();
        final SpringMesh mesh = entry.getValue();
        final Set<PointMatch> matches = mesh.getVA().keySet();
        Rectangle box = patch.getCoordinateTransformBoundingBox();

        /* compensate for existing coordinate transform bounding box */
        for (final PointMatch pm : matches) {
          final Point p1 = pm.getP1();
          final double[] l = p1.getL();
          l[0] += box.x;
          l[1] += box.y;
        }

        final MovingLeastSquaresTransform2 mlt = new MovingLeastSquaresTransform2();
        mlt.setModel(AffineModel2D.class);
        mlt.setAlpha(2.0f);
        mlt.setMatches(matches);

        patch.appendCoordinateTransform(mlt);
        box = patch.getCoordinateTransformBoundingBox();

        patch.getAffineTransform().setToTranslation(box.x, box.y);
        patch.updateInDatabase("transform");
        patch.updateBucket();

        patch.updateMipMaps();
      }
    }

    Utils.log("Done.");
  }
Example #9
0
 @Override
 public synchronized Collection<Long> getLayerIds() {
   final HashSet<Long> lids = new HashSet<Long>();
   for (final Item item : al_items) lids.addAll(Utils.asList(item.p_layer, 0, item.n_points));
   return lids;
 }
Example #10
0
  @Override
  public void mousePressed(
      final MouseEvent me, final Layer la, int x_p, int y_p, final double mag) {
    final int tool = ProjectToolbar.getToolId();
    if (ProjectToolbar.PEN != tool) return;

    final long lid = la.getId(); // isn't this.layer pointing to the current layer always?

    // transform the x_p, y_p to the local coordinates
    if (!this.at.isIdentity()) {
      final Point2D.Double p = inverseTransformPoint(x_p, y_p);
      x_p = (int) p.x;
      y_p = (int) p.y;
    }

    // find if the click is within radius of an existing point for the current layer
    for (final Item tmp : al_items) {
      index = tmp.find(lid, x_p, y_p, mag);
      if (-1 != index) {
        this.item = tmp;
        break;
      }
    }

    // final boolean is_zoom_invariant = "true".equals(project.getProperty("dissector_zoom"));

    // TODO: if zoom invariant, should check for nearest point. Or nearest point anyway, when
    // deleting
    // (but also for adding a new one?)

    if (me.isShiftDown() && Utils.isControlDown(me)) {
      if (-1 != index) {
        // delete
        item.remove(index);
        if (0 == item.n_points) al_items.remove(item);
        item = null;
        index = -1;
        Display.repaint(layer_set, this, 0);
      }
      // in any case:
      return;
    }
    if (-1 != index) return;
    // else try to add a point to a suitable item
    // Find an item in the previous or the next layer,
    //     which falls within radius of the clicked point
    try {
      for (final Item tmp : al_items) {
        index = tmp.add(x_p, y_p, la);
        if (-1 != index) {
          this.item = tmp;
          return;
        }
      }
      // could not be added to an existing item, so creating a new item with a new point in it
      int max_tag = 0;
      for (final Item tmp : al_items) {
        if (tmp.tag > max_tag) max_tag = tmp.tag;
      }
      int radius = 8; // default
      if (al_items.size() > 0) radius = al_items.get(al_items.size() - 1).radius;
      this.item = new Item(max_tag + 1, radius, x_p, y_p, la);
      index = 0;
      al_items.add(this.item);
    } finally {
      if (null != item) {
        bbox = this.at.createTransformedShape(item.getBoundingBox()).getBounds();
        Display.repaint(layer_set, bbox);
      } else Display.repaint(layer_set, this, 0);
    }
  }