2
$\begingroup$

Consider a binary mask as

Image[DiskMatrix[All,{100,150}]];

enter image description here

Now I wish to have a strip like this:

enter image description here

such that I can manipulate the inner radius, and the outer radius (here major and minor axes) without changing the original image size.

How can I do this?

Edit 1:

I just figured out that I can do this in the following way:

Manipulate[mask1 = Image[DiskMatrix[{100*m, 150*m}, {100, 150}]];
 mask2 = Image[DiskMatrix[{100*n, 150*n}, {100, 150}]];
 ImageSubtract[mask1, ImageMultiply[mask1, mask2]], {m, 0, 0.5},
 {n, 0, m}]

Is there any better way to do this?

$\endgroup$
  • 1
    $\begingroup$ you should make your last edit an answer. Seems pretty good, what do you want for "better" ? $\endgroup$ – george2079 Jan 4 '18 at 16:06
  • $\begingroup$ @george2079 Thanks. I was thinking whether it can be done more easily. $\endgroup$ – Majis Jan 4 '18 at 16:09
2
$\begingroup$

If by "shrinking" you mean something like carving an n-pixel wide border from the mask, you can do this using morphological erosion with a disk structuring element

img = Image[DiskMatrix[All, {100, 150}]];    
r1 = Erosion[img, DiskMatrix[10], Padding -> 0]

enter image description here

r2 = Erosion[img, DiskMatrix[20], Padding -> 0]

enter image description here

r1 - r2

enter image description here

Alternatively, you can use a distance transform to calculate the euclidean distance of each point in the mask to the background:

dist = DistanceTransform[img, Padding -> 0];
ListPlot3D[ImageData[dist]]

enter image description here

You can then use simple algebra to select the pixels at certain distances from the border:

UnitStep[dist - 10] - UnitStep[dist - 20]

(same result)

enter image description here

$\endgroup$
1
$\begingroup$

Here is another way:

With[{w = 100, h = 150, m = 3, n = 2},
  Image@BitXor[
    DiskMatrix[All, m {w, h}], 
    CenterArray[DiskMatrix[All, n {w, h}], m {w, h}]
  ]
]
$\endgroup$
1
$\begingroup$

another approach. (watch, this gets real slow if you try to make it any larger)

size = {100, 200}
Manipulate[
 Image[SparseArray[{i_, j_} /; 
     a^2 < r (i - size[[1]]/2)^2 + (j - size[[2]]/2)^2 < b^2 -> 1, 
   size]],
 {{a, 10}, 0, 100},
 {{b, 50}, 0, 100},
 {{r, 2}, 1, 10}]
$\endgroup$
1
$\begingroup$

I acknowledge other answers. However, I think I am happy with this one.

Manipulate[
 mask1 = Image[DiskMatrix[{100*m[[2]], 150*m[[2]]}, {100, 150}]];
 mask2 = Image[DiskMatrix[{100*m[[1]], 150*m[[1]]}, {100, 150}]];
 ImageSubtract[mask1, ImageMultiply[mask1, mask2]],
 {m, 0, 0.5, ControlType -> IntervalSlider, Method -> "Push", 
  MinIntervalSize -> 0.01}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.