Affine Transform of Masks

Dear all,

I’m trying to draw stick like shapes in my images, like this example delta2DStick.tiff (3.0 MB). To do so, I take a 2D box mask, using WritableBox and rotate and translate it, which leads to the sort of broken shapes you see in the attached image (Note that to transform masks into iterable intervals, I do as
suggested in https://forum.image.sc/t/examples-of-usage-of-imglib2-roi/22855/8)
I would’ve used the line mask, but the problem is that I can’t define thickness for lines.
This is all happening because LineRegionOfInterest is deprecated by the way.

Any suggestions how I should go about this? Note that it’s not 100% essential for me to use masks to draw lines, I can use any other class you may suggest.

1 Like

Seems strange that the 90-degree rotation would result in a line that isn’t straight. Any thoughts @tpietzsch?

Let’s say there’s a infinitesimal deviation from 90. I think it still shouldn’t be this horrible.

I also like to bring attention to the fact that the line thickness changes between rotations too.

By the way, the sticks are broken particularly in the middle. I actually start from a stick located at the origin (positive and negative coordinates) and then translate and rotate it. So that the rip in the middle could be due to this!

I think one problem might be that the outlines go right along pixel centers, so that infinitesimal deviations can push a pixel one way or the other. I would try to add 0.5 on either side to put the outline “along pixel cracks…”. In practice, for WritableBox, if your center point is at a pixel center (e.g., the origin), try making the sidelength an odd number.

1 Like

Thanks for the reply @tpietzsch
So you mean the length should be 0 ± x, where x is an odd number?

I actually believe the problem is that the underlying mask has real values, and then we make them discrete using converters, whereas an actual line drawing algorithm assumes pixels are discrete.
What do you think?

the total length x should be odd, and then it will be 0 ± x/2

I agree to the statements “the problem is that the underlying mask has real values, and then we make them discrete using converters” and “an actual line drawing algorithm assumes pixels are discrete”, but I don’t fully see how they are related

At least for my case, a line drawing algorithm where I could specify the thickness of the line would’ve sufficed (like Line class “ij.gui.Line” in ImageJ1).

Dear @tpietzsch
I’m still stuck on this issue. I was wondering if it’s possible to add some form of line Mask with a thickness that would not have the same as we discussed here.

Did you try the “making sidelength an odd number” suggestion? And the problem still occurs? Could you post a minimal example to reproduce?
(I expect, that a line Mask would be only a bit of syntactic sugar on top of that concept. I don’t see how it would be done fundamentally different.)

There is also a class IterableLine which you could use to do Bresenham line painting, but that doesn’t have a thickness, so probably it is also not what you need. But maybe you can use it to get a solution.

(For usage see the test https://github.com/imglib/imglib2-roi/blob/2e2e753728bb3210f68538b63cba3b3465696d51/src/test/java/net/imglib2/roi/geom/integer/IterableLineTest.java)

Thanks Tobias for your response and suggestions,

I did apply your suggestion, didn’t work.

It’s kind of difficult for me to send a minimal example, given that I’ve used this method as part of a software that I’m writing. Hence, difficult to to post what’s going on. But basically, its nothing more than applying an affine transform to a mask.

I’d say though that if we were to use a transformed masked to iterate over a specific region of an image, those aberrations around the border may cause some problem. So I’d say implementing a line mask with thickness is justified (at least for my case :D). What would be more interesting I guess is to implement discrete masks as well as continuous masks in general, because as we said this problem happens when we transform continuous masks to discrete ones.

Anyway, if I can’t find a solution, I may have to use ImageJ1 line class, but I hope not!

Thanks,