ctrueden on roitree-to-mask-converters
ctrueden on master
First cut: ROITree to SuperElli… Fill out ROITree <-> single mas… Add RealMask support and 9 more (compare)
ctrueden on roitree-to-mask-converters
First cut: ROITree to SuperElli… Fill out ROITree <-> single mas… Add RealMask support and 8 more (compare)
ctrueden on master
POM: add main-class for quick t… (compare)
tinevez on dev
Add Vlado as a contributor Merge pull request #178 from xu… (compare)
ctrueden on opSearchResult-improvements
Use stream(), not parallelStrea… OpListingInfo: ensure OpService… OpList: improve equals implemen… (compare)
RealMaskRealInterval myMask = ...;
RandomAccessible<T> myImage = ...;
IterableInterval<T> myMaskedImage = Regions.sample(myMask, myImage);
Cursor<T> c = myMaskedImage.localizingCursor();
long[] pos = new long[c.numDimensions()];
while (c.hasNext()) {
T value = c.next();
c.localize(pos);
// and now we do something with the position and sample value
}
myMask
has to be a RealMaskRealInterval
, not a RealMask
. This is unfortunate. We could add a Regions.sample(RealMask, RandomAccessibleInterval)
that creates a RealMaskRealInterval
matching the bounds of the given RAI. I think?myMaskedImage
cannot be used with LoopBuilder
because LoopBuilder
only supports RAI images, not II images. So we have to use this clunkier cursor code, rather than a nice lambda. ¯\_(ツ)_/¯
RealMask
(not necessarily a RealMaskRealInterval
) and a RAI and you want to combine them.
RandomAccessible
and IntervalView
, see imagej-roi-course
@NicoKiaru I have the following workflow:
Source
) and view it in BDV.AffineTransform
using the manual transform UI of BDV*.xml
file that looks exactly as the original one that I opened, but I want a new <affine>...</affine>
content, reflecting the additional transform that I manually added in BDV.Do you know how to do this most efficiently? Do I have to construct a new SpimData
object from the TransformedSource
and then use XmlIoSpimData.save()
? If so, would you have code already to construct SpimData
from a single Source
and the path to the corresponding .h5 file? Or are there other ways to save such an .xml
file?
spimData.getViewRegistrations().getViewRegistration(timePoint,iViewSetup).preconcatenateTransform(myAffineTransform);
or spimData.getViewRegistrations().getViewRegistration(timePoint,iViewSetup).concatenateTransform(myAffineTransform);
, with myAffineTransform
being the transform retrieved from the TransformedSource
. Then you can resave the dataset. FYI, I also found a trick to update the spimData
when it's shown in the bdv (thanks to reflection to access a private method see https://github.com/BIOP/bigdataviewer_scijava/blob/master/src/main/java/ch/epfl/biop/bdv/scijava/command/spimdata/UpdateSpimDataDisplay.java)
loadTimepoint
method in AbstractSpimSource
was made public, then it would be a bit easier. (https://github.com/bigdataviewer/bigdataviewer-core/blob/5be52618026c6734911d9c150a9e2ba1140799e0/src/main/java/bdv/AbstractSpimSource.java#L187)
@StephanPreibisch somehow I do not manage. It is not updating the image in BDV. Probably I am doing something wrong:
final Source< ? > source = bdv.getBdvHandle().getViewerPanel().getState().getSources().get( currentSource ).getSpimSource();
final SpimData spimData = sourceToSpimData.get( source );
spimData.getViewRegistrations().getViewRegistration( 0, 0 ).concatenateTransform( new ViewTransformAffine( "My transform", myTransfrom ) );
spimData.getViewRegistrations().getViewRegistration( 0, 0 ).updateModel();
bdv.getBdvHandle().getViewerPanel().requestRepaint();
sourceToSpimData
is a Map
that I generate while adding new SpimData
to BDV in order to keep track of things.
updateModel
function is useful for updating properly the SpimData object before saving it, but I'm nor sure..
SpimSource.loadTimepoints
method through reflection
Thanks @NicoKiaru & @StephanPreibisch !
It looks like that both of your codes you are calling a method of the Source
that is wrapped by the TransformedSource
, which is the object BDV is using to display the source. What I did initially was simply:
final TransformedSource transformedSource = ( TransformedSource ) source;
transformedSource.setFixedTransform( myTransform );
bdv.getBdvHandle().getViewerPanel().requestRepaint();
This updates the display of the TransformedSource
in the BDV and is much simpler code. I think the difference is that the TransformedSource
is something that only exists in BDV and is not talking back to the SpimData
object that was initially put into BDV for display. My feeling is that if one just wants to add additional transforms to Source
s and display those in BDV, using the TransformedSource.setFixedTransform()
approach might be cleaner?! In fact, the only reason I now also want to modify the SpimData
object is because I want to save a new xml with myTransform
appearing as additional <affine>...<\affine>
tags. What do you think?
ManualTransformation
(by pressing T
in BDV
) and/or adding any kind of other transformation, e.g. as obtained by a phase-correlation algorithm. And they should play well together. E.g. a user might do a rough manual pre-alignment (using T
) and then press, e.g., P
to compute a fine phase-correlation alignment on top of the manual pre-alignment. I am a bit worried right now that the current ManualTransformation
in bdv-core relies on the TransformedSource
, while our solutions seem to rather work through SpimData
, and thus things might become messy, but I might be wrong as I am still not fully grasping everything...
SpimData
option. Extra advantage of using SpimData is that the volatile view is taken care of also. It may not be the case fot the TransformedSource
? An alternative : every time you want to save the SpimData, check the transform of the TransformedSource
: if it's not identity, then push it to SpimData
.
ViewRegistration
in the SpimData
and also applied your reflection trick, in above example applying a simple translation along the x-axis. The result in BDV
is that the yellow box is shifted along the x-axis relative to the grey square (see screenshot). However the coordinates of the upper left corner of the image are still at x=0 and y=0 if you hover there with the mouse. If I would change the transformation via the TransformedSource.setFixTransform()
this would be different: the coordinates of the image would actually be shifted. Can someone explain me the meaning of the gray square and why the coordinates do not change using the SpimData
approach? (...for me, I think the coordinates really would need to change because I need to move around the relative location of multiple Sources in a physical coordinate system).
LoopBuilder
but that requires a lambda. I want to do this from Python and I'm concerned that writing the lambda will not be elegant and/or performant. My current approach is to use Ops (ij.op().run("copy.rai", result, rai)
) but @haesleinhuepf says in imagej/pyimagej#46 that it is too slow and must be fixed immediately.
Source< ? >
and the Source< ? extends <Volatile< ? >>
. An alternative to twice calling the private loadTimepoint()
method via reflection seems to be to simply use transformedSource.setFixedTransform( transform )
. This also properly updates the BDV. I don't understand yet what the pros and cons are...