napari-imagej icon indicating copy to clipboard operation
napari-imagej copied to clipboard

Mutable Layers aren't auto-contrasted

Open gselzer opened this issue 2 years ago • 7 comments

Here's an example, running the image.invert Op. ops_don't_auto_contrast

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?

gselzer avatar Oct 25 '22 16:10 gselzer

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!

elevans avatar Oct 25 '22 16:10 elevans

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.

ctrueden avatar Oct 25 '22 16:10 ctrueden

For inplace ops though, I think it could be annoying in some cases. So my vote is yes for computers, no for inplaces.

Do Modules 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?

gselzer avatar Oct 25 '22 16:10 gselzer

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.

ctrueden avatar Oct 25 '22 18:10 ctrueden

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.

gselzer avatar Oct 25 '22 18:10 gselzer

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.

ctrueden avatar Oct 25 '22 21:10 ctrueden

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

gselzer avatar Dec 15 '22 19:12 gselzer

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?

hinerm avatar Oct 15 '24 16:10 hinerm

I tried reproducing this, but I cannot, however I encountered a new issue, which I describe in #300.

gselzer avatar Oct 15 '24 18:10 gselzer