[英]Matlab: How to bend line in image
我手中有一張圖片(png格式)。 限制橢圓(代表原子核)的線在直線上,這是不切實際的。 我如何才能從圖像中提取線條並使它們彎曲,並且前提是它們仍然包圍核。
以下是圖像:
彎曲后
編輯 :如何將答案2中的“ 擴張和過濾”部分轉換為Matlab語言? 我不知道。
您所輸入的是Voronoi圖。 您可以使用另一個距離函數而不是歐幾里得來重新計算它。
這是Mathematica中使用“曼哈頓距離”的示例( i3
是沒有線條的輸入圖像):
ColorCombine[{Image[
WatershedComponents[
DistanceTransform[Binarize@i3,
DistanceFunction -> ManhattanDistance] ]], i3, i3}]
編輯
我正在使用另一種算法(初步結果)。 你怎么看?
好的,這是一種涉及獲得“自然”非對稱外觀所需的幾個隨機化步驟的方法。
我在Mathematica中發布了實際的代碼,以防萬一有人在乎將其翻譯為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的閱讀器,最后一個循環的功能代碼可能更容易(或更短):
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]
這是我想出的,它不是@belisarius代碼的直接翻譯,但應該足夠接近。
%# read image (indexed image)
[I,map] = imread('http://i.stack.imgur.com/YENhB.png');
%# extract the blobs (binary image)
BW = (I==1);
%# skeletonization + dilation
BW = bwmorph(BW, 'skel', Inf);
BW = imdilate(BW, strel('square',2*1+1));
%# connected components
L = bwlabel(BW);
imshow(label2rgb(L))
%# filter 15x15 neighborhood
for i=1:13
L = nlfilter(L, [15 15], @myFilterFunc);
imshow( label2rgb(L) )
end
%# result
L(I==1) = 0; %# put blobs back
L(edge(L,'canny')) = 0; %# edges
imshow( label2rgb(L,@jet,[0 0 0]) )
function p = myFilterFunc(x)
if range(x(:)) == 0
p = x(1); %# if one color, return it
else
p = mode(x(x~=0)); %# else, return the most frequent color
end
end
結果:
這是該過程的動畫:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.