napari-imagej
napari-imagej copied to clipboard
Mutable Layers aren't auto-contrasted
Here's an example, running the image.invert
Op.
The output looks blank until you press the contrast button.
It's super easy to fix this by resetting the contrast of any mutable layers. I've actually already coded up the fix on my machine...
The question is: should we reset the contrast?
Factors:
- Does ImageJ2/Fiji reset the contrast for mutable outputs? I can't even get this Op to work in Fiji...
- Would anybody actually not want it to be autocontrasted? In this case, users might think that the Op doesn't work if we don't autocontrast...
@elevans @ctrueden do you have opinions?
As a consumer I find image outputs that haven't had their contrast auto adjusted to be really annoying. Without fail my first action is to call up the auto contrast function on the image. If I remember correctly there are a few places in ImageJ (maybe plugins?) that apply the auto contrast adjustments to the image before returning them to the user. Thus in my mind there is no particular we should not return an adjusted image.
I also feel like this could mitigate users being confused with outputs. They may think nothing happened...when indeed it did!
I cannot think of a better solution that auto-scaling after running a computer op. The output container is supposed to be empty, after all. And it is highly unlikely they will pass in a metadata-rich image (e.g. DatasetView
) that already has appropriate min/max bounds preset.
For inplace ops though, I think it could be annoying in some cases. So my vote is yes for computers, no for inplaces.
For inplace ops though, I think it could be annoying in some cases. So my vote is yes for computers, no for inplaces.
Do Module
s retain that information? If not, then there's no way for us to know - any fix would be really HACK-y/involve a lot of case logic.
Can you elaborate on the cases you're thinking of?
For plain modules, there is no such things as a computer. Any "both" input is assumed to be inplace mutation.
Can you elaborate on the cases you're thinking of?
Here is an example: suppose you run a module that adds 10 to every pixel. If you reautoscale, it will look like nothing changed. Whereas the user will probably be expecting everything to get brighter.
For plain modules, there is no such things as a computer. Any "both" input is assumed to be inplace mutation.
Woah, that's news to me. Is that documented, or just what happens in practice?
If that's the case, then the only way I can think of to auto-contrast computer outputs only is to hardcode checks on the name of the output (because Computer
outputs are always named out
and Inplace
outputs are always named arg
. Can you think of a better way @ctrueden?
Here is an example: suppose you run a module that adds 10 to every pixel. If you reautoscale, it will look like nothing changed. Whereas the user will probably be expecting everything to get brighter.
Thanks, that helps.
We might be talking past each other here. There is a such thing as a computer op in ImageJ Ops v1. But in the SciJava module system generally, there is no such thing as function/computer/inplace/etc. Those "special op types" are an Ops construction. Above, I am speaking about the SciJava module system in general; the only things it has for parameter types are INPUT, OUTPUT, and BOTH.
That said, it gets confusing because ImageJ Ops v1 ops are (inheritance) SciJava commands. You can of course tell the difference between a computer op vs an inplace op based on which interfaces/classes it implements/extends. But if you treat them as plain SciJava commands, without special-case checking them for "op-ness", you won't know if they are computers vs inplaces.
I hope by now it is clear that I am not in favor of running ImageJ Ops in such as a way, as normal SciJava modules, via the run
methods of ModuleService
or CommandService
. Ops should only be run via the OpService
; I consider the fact that Op
extends Command
to be a mistake.
With respect to napari-imagej, I don't know how you are running ops right now, but I thought you said you were using the OpService
. If that's the case, we can indeed autoscale computer ops, and leave the scaling of existing layers fed into inplaces alone. All I am saying above is that when running something that is not an op, but rather some other kind of SciJava command or script module, executed via ModuleService#run
, any BOTH
parameter should not autoscaled.
But if you treat them as plain SciJava commands, without special-case checking them for "op-ness", you won't know if they are computers vs inplaces.
Yup, that's what we're doing. It makes things simple, as we only need to think about them as Modules, and, due to the OpListing
work, means that we can still use OpService.run
Looking at the animation, when we see the original brick
image the contrast range is maximized and the image displays fine. So I am questioning if the black image post-inversion is actually because of a contrast issue, or are we just missing a repaint
kind of trigger when running the Op, which is hit when using the auto contrast button?
I tried reproducing this, but I cannot, however I encountered a new issue, which I describe in #300.