Original attempt, experimentation
OK, I have an answer based on an alpha channel but it required more morphological manipulations first.
The good thing is that it should work for other shapes, and requires only the final product newimage
. However, to make it work reliably, I needed to increase the image size to avoid some boundary lines bleeding into each other.
newimage =
ImageResize[
Colorize[regions,
ColorFunction -> (ColorData["SolarColors", Mod[Sin[#^2], 1]] &),
ColorFunctionScaling -> False], Scaled[1]]
Here is the image processing:
imAlpha = ImageCompose[
newimage,
SetAlphaChannel[#, ColorNegate[#]] &@Erosion[
FillingTransform@SelectComponents[
MorphologicalPerimeter[
Binarize[newimage],
CornerNeighbors -> False
],
"EnclosingComponentCount", # == 1 &
], .5
]
]

Edit: streamlined version
Now I combined my approaches from above (which relies on SelectComponents
) with the border color selection from this earlier answer (using Binarize
with a custom test function) to make a function deleteBorder
that can remove a homogeneous border background from an arbitrary image im
:
Options[deleteBorder] = {Tolerance -> .005};
deleteBorder[im_, OptionsPattern[]] := Module[{
rgb = ImageData[ColorConvert[im, "RGB"]][[2, 2]],
tol = OptionValue[Tolerance]
},
SetAlphaChannel[im, ColorNegate[#]] &@
SelectComponents[Binarize[im, Norm[# - rgb] <= tol &],
"EnclosingComponentCount", # == 0 &
]
]
It works by setting the alpha channel to a binarized version of im
in which the outermost region is transparent.
Here is another example:
im2 = Rasterize[
ParametricPlot3D[{Sin[4 Pi t], Cos[3 Pi t],
Sin[2 Pi t + Pi/3]}, {t, 0, 4},
PlotStyle -> {Brown, Tube[.03]}, Lighting -> "Neutral",
Background -> Green, Boxed -> False, Axes -> False], "Image",
ImageSize -> 450]

deleteBorder[im2]

You can now superimpose this result on any other image and the border region (appearing white above) will show as transparent. E.g., try Show[%, Background -> Red]
.
To show that this works independently of the background color, let's do:
im3 = Rasterize[
ParametricPlot3D[{Sin[4 Pi t], Cos[3 Pi t],
Sin[2 Pi t + Pi/3]}, {t, 0, 4},
PlotStyle -> {Yellow, Tube[.03]}, Lighting -> "Neutral",
Background -> Magenta, Boxed -> False, Axes -> False], "Image",
ImageSize -> 450]

Show[deleteBorder[im3], Background -> Red]

Edit 2: combining with DeleteBorderComponents
The question has an image whose border has different uniform colors in different pieces and perhaps these pieces are disjoint, as shown here:
g = {{Circle[#, 1 - Sqrt[2]/2] & /@
Tuples[0.5 {-1, 1}, 2]}, {Circle[{0, 0}, 1]}};
graphic =
Graphics[GeometricTransformation[g, Tuples[Range[-2, 2], 2]],
PlotRangePadding -> None];
image = Rasterize[graphic, "Image", ImageSize -> 800];
regions = MorphologicalComponents[image, 0.9];
newimage =
ImageResize[
Colorize[regions,
ColorFunction -> (ColorData["SolarColors", Mod[Sin[#^2], 1]] &),
ColorFunctionScaling -> False], Scaled[1]];
Here is a very simple way to do make the border black:
DeleteBorderComponents[newimage]

Here I use the built-in function DeleteBorderComponents
to immediately get rid of the border and set its color to Black
.
That's all there is to it - this basically is the simplest answer to the original question! But it's the boring route.
With my function deleteBorder
you can go much further than this:
Show[deleteBorder[DeleteBorderComponents[newimage]],
Background -> Blue]

deleteBorder
replaces Black
by a transparent region. This actually makes the black lines between the circles transparent too, and we can now still choose an arbitrary background color (Blue
), or superimpose the result onto a different image.
DeleteBorderComponents
- see my updated answer. Still, combining it with an alpha channel gives more flexibility, so I defined a new functiondeleteBorder
for that purpose. $\endgroup$DeleteBorderComponents
claims to only work for binary images (and matrices.) $\endgroup$deleteBorder
function I defined is of much more general utility. $\endgroup$