Mathematica- RMagick에서 이미지에서 흰색 배경을 제거하고 투명하게 만드는 작업을 수행하려고합니다 .
그러나 실제 사진에서는 (이미지 주위에 후광이있는 것처럼) 형편 없게 보입니다.
지금까지 시도한 내용은 다음과 같습니다.
unground0[img_] := With[{mask = ChanVeseBinarize[img, TargetColor->{1.,1.,1.}]},
Rasterize[SetAlphaChannel[img, ImageApply[1-#&, mask]], Background->None]]]
다음은 그 기능의 예입니다.
원본 이미지 :
흰색 배경이 배경없이 대체 된 이미지 (또는 여기에서 데모 목적으로 분홍색 배경) :
그 후광을 없애기위한 아이디어가 있습니까? LevelPenalty와 같은 것을 조정하면 이미지의 일부를 잃는 대신 후광이 사라지도록 할 수 있습니다.
편집 : 그래서 현상금에 대한 솔루션을 비교할 수 있습니다. 위와 같이 솔루션을 구성하십시오. 즉 이미지를 가져 와서 투명한 배경으로 이미지를 반환하는 unground-something이라는 자체 포함 함수입니다.
답변
필요한 가장자리 품질에 따라 다음과 같이 할 수 있습니다.
img = Import@"http://i.stack.imgur.com/k7E1F.png";
mask = ChanVeseBinarize[img, TargetColor -> {1., 1., 1.}, "LengthPenalty" -> 10]
mask1 = Blur[Erosion[ColorNegate[mask], 2], 5]
Rasterize[SetAlphaChannel[img, mask1], Background -> None]
편집하다
img2 = Import@"http://i.stack.imgur.com/k7E1F.png";
(*key point:scale up image to smooth the edges*)
img = ImageResize[img2, 4 ImageDimensions[img2]];
mask = ChanVeseBinarize[img, TargetColor -> {1., 1., 1.}, "LengthPenalty" -> 10];
mask1 = Blur[Erosion[ColorNegate[mask], 8], 10];
f[col_] := Rasterize[SetAlphaChannel[img, mask1], Background -> col,
ImageSize -> ImageDimensions@img2]
GraphicsGrid[{{f@Red, f@Blue, f@Green}}]
클릭하면 확대됩니다
편집 2
이미지 의 후광 과 배경 결함 의 정도에 대한 아이디어를 얻으려면 :
img = Import@"http://i.stack.imgur.com/k7E1F.png";
Join[{img}, MapThread[Binarize, {ColorSeparate[img, "HSB"], {.01, .01, .99}}]]
ColorNegate@ImageAdd[EntropyFilter[img, 1] // ImageAdjust, ColorNegate@img]
답변
이 기능은 작지만 눈에 띄는 개선을 위해 Mark Ransom이 설명한 역방향 혼합을 구현합니다.
reverseBlend[img_Image, alpha_Image, bgcolor_] :=
With[
{c = ImageData[img],
a = ImageData[alpha] + 0.0001, (* this is to minimize ComplexInfinitys and considerably improve performance *)
bc = bgcolor},
ImageClip@
Image[Quiet[(c - bc (1 - a))/a, {Power::infy,
Infinity::indet}] /. {ComplexInfinity -> 0, Indeterminate -> 0}]
]
이것은 배경 제거 기능입니다. threshold
매개 변수 이미지의 이진화 초기에 사용되면,이 minSizeCorrection
이진화 후 제거되는 작은 쓰레기 성분의 크기 한도를 미세하게 조정할 것이다.
removeWhiteBackground[img_, threshold_: 0.05, minSizeCorrection_: 1] :=
Module[
{dim, bigmask, mask, edgemask, alpha},
dim = ImageDimensions[img];
bigmask =
DeleteSmallComponents[
ColorNegate@
MorphologicalBinarize[ColorNegate@ImageResize[img, 4 dim], threshold],
Round[minSizeCorrection Times @@ dim/5]];
mask = ColorNegate@
ImageResize[ColorConvert[bigmask, "GrayScale"], dim];
edgemask =
ImageResize[
ImageAdjust@DistanceTransform@Dilation[EdgeDetect[bigmask, 2], 6],
dim];
alpha =
ImageAdd[
ImageSubtract[
ImageMultiply[ColorNegate@ColorConvert[img, "GrayScale"],
edgemask], ImageMultiply[mask, edgemask]], mask];
SetAlphaChannel[reverseBlend[img, alpha, 1], alpha]
]
기능 테스트 :
img = Import["http://i.stack.imgur.com/k7E1F.png"];
background =
ImageCrop[
Import["http://cdn.zmescience.com/wp-content/uploads/2011/06/\
forest2.jpg"], ImageDimensions[img]];
result = removeWhiteBackground[img]
ImageCompose[background, result]
Rasterize[result, Background -> Red]
Rasterize[result, Background -> Black]
작동 방식에 대한 간략한 설명 :
-
비교적 정확한 날카로운 모서리를 생성하는 선호하는 이진화 방법을 선택하십시오.
-
확대 된 이미지에 적용한 다음 얻은 이미지
mask
를 원래 크기 로 축소합니다 . 이것은 우리에게 앤티 앨리어싱을 제공합니다. 대부분의 작업이 완료되었습니다. -
약간 개선하려면 네거티브의 밝기를 알파로 사용하여 이미지를 배경에 혼합 한 다음 얻은 이미지를 가장자리 주변의 얇은 영역 (
edgemask
) 에서 원본 위에 혼합하여 가장자리 의 흰색 픽셀의 가시성을 줄입니다. 이러한 연산에 해당하는 알파 채널이 계산됩니다 (다소 비밀스러운ImageMultiply/Add
표현). -
이제 우리는 리버스 블렌드를 할 수 있도록 알파 채널의 추정치를 얻었습니다.
3 단계와 4 단계는 그다지 개선되지 않지만 차이는 눈에 보입니다.
답변
저는 Mathematica와 관련하여 구체적으로 언급하지 않고 일반적으로 말하겠습니다. 나는 이러한 작업이 어렵거나 사소한 것인지 전혀 모릅니다.
첫 번째 단계는 이미지 가장자리의 픽셀에 대한 알파 (투명도) 수준을 추정하는 것입니다. 지금은 엄격한 임계 값을 사용하고 있으므로 알파는 완전 투명 0 % 또는 완전 불투명 100 %입니다. 배경의 전체 흰색과 이미지의 일부인 색상 사이의 범위를 정의하고 적절한 비율을 설정해야합니다. 색상이 배경에 더 가까우면 알파가 낮고 더 어두운 컷오프에 더 가까우면 적절한 비율을 설정해야합니다. 높은 알파. 그 후에 주변 알파 값을 기준으로 조정할 수 있습니다. 픽셀이 투명도로 둘러싸 일수록 자체적으로 투명해질 가능성이 높습니다.
알파 값이 있으면 적절한 색상을 얻기 위해 역 블렌드를 수행해야합니다. 이미지가 배경 위에 표시 될 때 수식하여 알파 값에 따라 배합 배경색이고 전경 색상이다. 귀하의 경우 배경은 흰색 (255,255,255)이고 전경색은 알 수 없으므로 공식을 반대로 바꿉니다 . 때 수식 0으로 나누기를 요구하지만, 색상이 문제 어쨌든 그래서 그냥 검은 색 또는 흰색으로 사용하지 않습니다.c = bc*(1-a)+fc*a
bc
fc
fc = (c - bc*(1-a))/a
a=0
답변
다음은 belisarius의 마스크 생성의 도움을 받아 Mark Ransom의 접근 방식을 구현하는 시도입니다.
개체의 경계를 찾습니다.
img1 = SetAlphaChannel[img, 1];
erosionamount=2;
mb = ColorNegate@ChanVeseBinarize[img, TargetColor -> {1., 1., 1},
"LengthPenalty" -> 10];
edge = ImageSubtract[Dilation[mb, 2], Erosion[mb, erosionamount]];
ImageApply[{1, 0, 0} &, img, Masking ->edge]
알파 값을 설정합니다.
edgealpha = ImageMultiply[ImageFilter[(1 - Mean[Flatten[#]]^5) &,
ColorConvert[img, "GrayScale"], 2, Masking -> edge], edge];
imagealpha = ImageAdd[edgealpha, Erosion[mb, erosionamount]];
img2 = SetAlphaChannel[img, imagealpha];
반전 색상 혼합 :
img3 = ImageApply[Module[{c, \[Alpha], bc, fc},
bc = {1, 1, 1};
c = {#[[1]], #[[2]], #[[3]]};
\[Alpha] = #[[4]];
If[\[Alpha] > 0, Flatten[{(c - bc (1 - \[Alpha]))/\[Alpha], \[Alpha]}], {0., 0.,
0., 0}]] &, img2];
Show[img3, Background -> Pink]
일부 가장자리에 흰색 보풀이있는 것을 알 수 있습니까? 첫 번째 이미지의 빨간색 윤곽선과 비교하십시오. 더 나은 에지 감지기가 필요합니다. 침 식량을 늘리면 보풀에 도움이되지만 다른면이 너무 투명 해 지므로 가장자리 마스크의 너비에 절충안이 있습니다. 하지만 블러 작업 자체가 없다는 점을 고려하면 꽤 좋습니다.
다양한 이미지에서 알고리즘을 실행하여 견고성을 테스트하고 얼마나 자동인지 확인하는 것은 유익 할 것입니다.
답변
초보자로서 놀기만하면됩니다. 얼마나 많은 도구를 사용할 수 있는지 놀랍습니다.
b = ColorNegate[
GaussianFilter[MorphologicalBinarize[i, {0.96, 0.999}], 6]];
c = SetAlphaChannel[i, b];
Show[Graphics[Rectangle[], Background -> Orange,
PlotRangePadding -> None], c]
답변
저는 이미지 처리에 완전히 익숙하지 않지만 여기에 버전 8의 새로운 형태 학적 이미지 처리 기능을 사용하여 얻은 결과가 있습니다.
mask = DeleteSmallComponents[
ColorNegate@
Image[MorphologicalComponents[ColorNegate@img, .062,
Method -> "Convex"], "Bit"], 10000];
Show[Graphics[Rectangle[], Background -> Red,
PlotRangePadding -> None], SetAlphaChannel[img, ColorNegate@mask]]
답변
이를 위해 Photoshop을 사용하고 PNG로 저장하는 것이 좋습니다.