问题描述
我手头有一张图片(png 格式).椭圆的边界线(代表核)过直,这是不切实际的.我怎样才能从图像中提取线条并使它们弯曲,前提是它们仍然包围着细胞核.
I have a image(png format) in hand. The lines that bound the ellipses (represent the nucleus) are over straight which are impractical. How could i extract the lines from the image and make them bent, and with the precondition that they still enclose the nucleus.
图片如下:
弯曲后
编辑:如何将 answer2 中的 Dilation And Filter 部分翻译成 Matlab 语言?我想不通.
EDIT: How can i translate the Dilation And Filter part in answer2 into Matlab language? I can't figure it out.
推荐答案
好的,这里有一个方法,需要几个随机化步骤来获得自然"的非对称外观.
Ok, here is a way involving several randomization steps needed to get a "natural" non symmetrical appearance.
我在 Mathematica 中发布了实际代码,以防万一有人愿意将其翻译成 Matlab.
I am posting the actual code in Mathematica, just in case someone cares translating it to Matlab.
(* A preparatory step: get your image and clean it*)
i = Import@"http://i.stack.imgur.com/YENhB.png";
i1 = Image@Replace[ImageData[i], {0., 0., 0.} -> {1, 1, 1}, {2}];
i2 = ImageSubtract[i1, i];
i3 = Inpaint[i, i2]
(*Now reduce to a skeleton to get a somewhat random starting point.
The actual algorithm for this dilation does not matter, as far as we
get a random area slightly larger than the original elipses *)
id = Dilation[SkeletonTransform[
Dilation[SkeletonTransform@ColorNegate@Binarize@i3, 3]], 1]
(*Now the real random dilation loop*)
(*Init vars*)
p = Array[1 &, 70]; j = 1;
(*Store in w an image with a different color for each cluster, so we
can find edges between them*)
w = (w1 =
WatershedComponents[
GradientFilter[Binarize[id, .1], 1]]) /. {4 -> 0} // Colorize;
(*and loop ...*)
For[i = 1, i < 70, i++,
(*Select edges in w and dilate them with a random 3x3 kernel*)
ed = Dilation[EdgeDetect[w, 1], RandomInteger[{0, 1}, {3, 3}]];
(*The following is the core*)
p[[j++]] = w =
ImageFilter[ (* We apply a filter to the edges*)
(Switch[
Length[#1], (*Count the colors in a 3x3 neighborhood of each pixel*)
0, {{{0, 0, 0}, 0}}, (*If no colors, return bkg*)
1, #1, (*If one color, return it*)
_, {{{0, 0, 0}, 0}}])[[1, 1]] (*If more than one color, return bkg*)&@
Cases[Tally[Flatten[#1, 1]],
Except[{{0.`, 0.`, 0.`}, _}]] & (*But Don't count bkg pixels*),
w, 1,
Masking -> ed, (*apply only to edges*)
Interleaving -> True (*apply to all color chanels at once*)]
]
结果是:
编辑
对于面向 Mathematica 的读者来说,最后一个循环的功能代码可能更容易(也更短):
For the Mathematica oriented reader, a functional code for the last loop could be easier (and shorter):
NestList[
ImageFilter[
If[Length[#1] == 1, #1[[1, 1]], {0, 0, 0}] &@
Cases[Tally[Flatten[#1, 1]], Except[{0.` {1, 1, 1}, _}]] & , #, 1,
Masking -> Dilation[EdgeDetect[#, 1], RandomInteger[{0, 1}, {3, 3}]],
Interleaving -> True ] &,
WatershedComponents@GradientFilter[Binarize[id,.1],1]/.{4-> 0}//Colorize,
5]
这篇关于Matlab:如何弯曲图像中的线条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!