[ENH] Image preprocess: masking#38
Conversation
|
All tests seem to be passing. Good for me! |
|
OK, could you give me example how I can use this? So that I know what to test? Thanks! |
|
@markotoplak , Please find an example workflow and a datafile which benefits from the usage of masking, here: Our idea was to use selections, groups to define the values that we mask out (not taken into account) in the preprocessors for the calculation of image corrections. The user can choose the desired group in the "Mask selection" box. The preprocessor UI is also updated with a checkbox to enable the mask for that specific preprocessor. |
|
@ngergihun, thanks for a clear usage example. Seems to work for me. Not connected with this PR, but... What does "Line leveling" actually do? Why does it seem to touch only the lines where both "squares" are present and not touch the rest (ok, it changes values but not the image)? Is this a lucky artifact? Here is the unmasked version of the data you showed me:
|
|
Oh, now I see it does not leave the background as it was.... Before there was a color gradient on it, now there is none. But would still like to know why is this useful... |
It is not only a background issue. In scanning probe microscopy, you scan the sample in a raster scan pattern; thus, you have a fast axis (horizontal) and a slow axis (vertical). Because of the instabilities of the measurement, the base values of the horizontal lines are not only monotonically offset relative to each other, but there is noise on the line offset values. This cannot be corrected by a background fit. The LineLevelling subtracts the mean or median value of a line. This only flattens the lines nicely if only the substrate level is considered in the calculation of the median values. The islands (in this example) disturb this method, because they do not represent the base value of the substrate. By masking, the user can exclude these values, which mislead the correction calculation. In the correction, we only want to take into account datapoints that belong to the region that you want to reference to (usually the substrate). This is also true for optical images. The example without masking out the island gives an incorrect result. That is why it is a good example. |
Thank you! Now I understand why masking allows actually getting the proper result and that what I showed is an artifact indeed. As a user maybe "Masking: enable" in the preprocessor does not seem that obvious. You decide - but I think it should be more explicit like "Mask: remove from averaging". I think it would also nice to have the other option, to choose how the mask would be used. Then instead of a checkbox, with could have a drop-down menu. Like "Mask: ignore | exclude mask (POSSIBLY from averaging) | include only mask" - here I could not think of nice names, but you'll get the idea. What do you think? |
Yes, we were thinking about this at some point. Sometimes it can be convenient to be able to exclude or include. |
|
@markotoplak , Thanks for the review, and sorry for the long delay. I tried to make the changes you suggested. So far, the (Ignore, exclude, include) data option for the mask usage in the preprocessor is only implemented for the LineLevel preprocessor at the moment. If we find it okay, then I will implement it for the other preprocessors where it makes sense. Thanks for the continuous support and suggestions. |
|
For starters I rebased this in 1 commit so that editing is easier, and also rebased to master. The history backup is in https://github.com/markotoplak/orange-snom/tree/masking20251221 |
|
@ngergihun, I am working on this, so the comments I write are mainly for myself. Don't worry about it. :) |
|
@borondics, @ngergihun, I made some structural changes to this PR.
As far as I see, regarding (1), I get the same thing as before with example from Jul 21. Regarding (2), workflows now load properly regardless of which value is selected (before that got reset sometimes). Workflows saved with the previous version won't load properly, but whatever you set anew and load should now work. Because I may have introduced new issues, testing is welcome. Pretty please. :) |
|
OK, this is probably it... In the end, when I was writing tests, I did not quite get why the complication with this mask and It would be nice to get a confirmation from you that this works before I make a Quasar package. For now, I'll just merge and if you have complaints, fix them later. |

We rediscussed with @borondics the way of using masks in OWPreprocessImage.
The conclusion was that probably the most flexible way is to use the categories of meta and class variables so the user could use any selection, cluster, etc, to define the mask.
This PR implements a 'Mask selection' box where the user can select the desired group. The synthesized mask is passed to the preprocessor, which is updated now through pySNOM.
Preprocess editors are also updated to enable or disable the use of the mask.
I tried to do it with the least amount of modifications.