의견에서 말했듯이 의료 이미지 등록은 많은 연구가 가능한 주제이며 전문가는 아닙니다. 내가 읽은 것에서 일반적으로 사용되는 기본 아이디어는 두 이미지 (당신의 경우 이미지와 미러 이미지) 사이의 매핑을 정의 한 다음 매핑이 적용되면 매끄러움과 이미지 유사성에 대한 에너지 용어를 정의하고 마지막으로 표준 (또는 경우에 따라 응용 프로그램 별) 최적화 기술을 사용하여이 매핑을 최적화합니다.
Mathematica에서 빠른 알고리즘을 해킹하여 이것을 보여줍니다. 입니다 하지 당신이 의료 응용 프로그램에서 사용해야하는 알고리즘, 기본적인 아이디어의 데모.
먼저 이미지를로드하고 미러링 하고이 이미지를 작은 블록으로 나눕니다.
src = ColorConvert[Import["http://i.stack.imgur.com/jf709.jpg"],
"Grayscale"];
mirror = ImageReflect[src, Left -> Right];
blockSize = 30;
partsS = ImagePartition[src, {blockSize, blockSize}];
partsM = ImagePartition[mirror, {blockSize, blockSize}];
GraphicsGrid[partsS]
일반적으로 키포인트 나 이미지 모멘트 등을 사용하여 대략적인 고정 등록을 수행하지만 이미지가 거의 중앙에 있으므로 생략합니다.
하나의 블록을보고 미러 이미지 대응 인 경우 :
{partsS[[6, 10]], partsM[[6, 10]]}
그것들은 비슷하지만 바뀌 었다는 것을 알 수 있습니다. 변화의 양과 방향은 우리가 찾으려고하는 것입니다.
일치 유사성을 정량화하기 위해 제곱 유클리드 거리를 사용할 수 있습니다.
ListPlot3D[
ImageData[
ImageCorrelate[partsM[[6, 10]], partsS[[6, 10]],
SquaredEuclideanDistance]]]
슬프게도,이 데이터를 사용하면 최적화가 생각보다 직접적으로 어려웠으므로 대신 2 차 근사를 사용했습니다.
fitTerms = {1, x, x^2, y, y^2, x*y};
fit = Fit[
Flatten[MapIndexed[{#2[[1]] - blockSize/2, #2[[2]] -
blockSize/2, #1} &,
ImageData[
ImageCorrelate[partsM[[6, 10]], partsS[[6, 10]],
SquaredEuclideanDistance]], {2}], 1], fitTerms, {x, y}];
Plot3D[fit, {x, -25, 25}, {y, -25, 25}]
이 함수는 실제 상관 함수와 같지 않지만 첫 번째 단계에 충분합니다. 모든 블록 쌍에 대해 이것을 계산해 봅시다 :
distancesFit = MapThread[
Function[{part, template},
Fit[Flatten[
MapIndexed[{#2[[2]] - blockSize/2, #2[[1]] - blockSize/2, #1} &,
ImageData[
ImageCorrelate[part, template,
SquaredEuclideanDistance]], {2}], 1],
fitTerms, {x, y}]], {partsM, partsS}, 2];
이는 최적화를위한 첫 번째 에너지 용어를 제공합니다.
variablesX = Array[dx, Dimensions[partsS]];
variablesY = Array[dy, Dimensions[partsS]];
matchEnergyFit =
Total[MapThread[#1 /. {x -> #2, y -> #3} &, {distancesFit,
variablesX, variablesY}, 2], 3];
variablesX/Y
는 각 블록에 대한 오프셋을 포함하고 오프셋이 matchEnergyFit
적용된 원본 이미지와 미러 이미지 사이의 제곱 유클리드 차이를 근사합니다.
이 에너지 만 최적화하면 결과가 수렴되지 않을 수 있습니다. 또한 블록 유사성이 오프셋에 대해 아무 것도 알려주지 않는 오프셋이 매끄 럽기를 원합니다 (예 : 직선 또는 흰색 배경).
평활도를위한 두 번째 에너지 용어를 설정했습니다.
smoothnessEnergy = Total[Flatten[
{
Table[
variablesX[[i, j - 1]] - 2 variablesX[[i, j]] +
variablesX[[i, j + 1]], {i, 1, Length[partsS]}, {j, 2,
Length[partsS[[1]]] - 1}],
Table[
variablesX[[i - 1, j]] - 2 variablesX[[i, j]] +
variablesX[[i + 1, j]], {i, 2, Length[partsS] - 1}, {j, 1,
Length[partsS[[1]]]}],
Table[
variablesY[[i, j - 1]] - 2 variablesY[[i, j]] +
variablesY[[i, j + 1]], {i, 1, Length[partsS]}, {j, 2,
Length[partsS[[1]]] - 1}],
Table[
variablesY[[i - 1, j]] - 2 variablesY[[i, j]] +
variablesY[[i + 1, j]], {i, 2, Length[partsS] - 1}, {j, 1,
Length[partsS[[1]]]}]
}^2]];
다행히 Mathematica에는 제약 최적화가 내장되어 있습니다.
allVariables = Flatten[{variablesX, variablesY}];
constraints = -blockSize/3. < # < blockSize/3. & /@ allVariables;
initialValues = {#, 0} & /@ allVariables;
solution =
FindMinimum[{matchEnergyFit + 0.1 smoothnessEnergy, constraints},
initialValues];
결과를 보자.
grid = Table[{(j - 0.5)*blockSize - dx[i, j], (i - 0.5)*blockSize -
dy[i, j]}, {i, Length[partsS]}, {j, Length[partsS[[1]]]}] /.
solution[[2]];
Show[src, Graphics[
{Red,
Line /@ grid,
Line /@ Transpose[grid]
}]]
0.1
요인은 전에 smoothnessEnergy
부드러움 에너지가 이미지 일치 에너지 용어와 관련하여 얻는 상대적 무게입니다. 다음은 서로 다른 가중치에 대한 결과입니다.
가능한 개선 사항 :
- 내가 말했듯이 먼저 엄격한 등록을 수행하십시오. 흰색 배경에서는 간단한 이미지 모멘트 기반 등록이 제대로 작동합니다.
- 이것은 한 단계 일뿐입니다. 한 단계에서 찾은 오프셋을 사용하고 두 번째 단계에서이를 개선 할 수 있습니다 (아마도 더 작은 검색 창 또는 더 작은 블록 크기).
- 블록 없이이 작업을 수행하는 기사를 읽었지만 픽셀 당 오프셋을 최적화합니다.
- 다른 평활도 기능을 사용해보십시오