ดังที่ฉันได้กล่าวไว้ในความคิดเห็นการลงทะเบียนอิมเมจทางการแพทย์เป็นหัวข้อที่มีงานวิจัยมากมายและฉันไม่ใช่ผู้เชี่ยวชาญ จากสิ่งที่ฉันได้อ่านแนวคิดพื้นฐานที่ใช้กันทั่วไปคือการกำหนดการแมประหว่างสองภาพ (ในกรณีของคุณเป็นรูปภาพและภาพสะท้อนในกระจก) จากนั้นกำหนดคำศัพท์ด้านพลังงานเพื่อความเรียบเนียนและเพื่อความคล้ายคลึงกันของภาพ ปรับการแมปนี้ให้เหมาะสมโดยใช้เทคนิคการเพิ่มประสิทธิภาพมาตรฐาน (หรือบางครั้งเฉพาะแอปพลิเคชัน)
ฉันแฮ็กอัลกอริทึมอย่างรวดเร็วใน 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]]]
น่าเศร้าที่การใช้ข้อมูลนี้เป็นการเพิ่มประสิทธิภาพโดยตรงนั้นยากกว่าที่ฉันคิดดังนั้นฉันจึงใช้การประมาณอันดับสองแทน:
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
ประมาณความแตกต่าง euclidean ยกกำลังสองระหว่างรูปภาพต้นฉบับและรูปภาพที่มิร์เรอร์โดยใช้ออฟเซ็ต
การเพิ่มประสิทธิภาพพลังงานนี้เพียงอย่างเดียวจะให้ผลลัพธ์ที่ไม่ดี (หากรวมกันทั้งหมด) นอกจากนี้เรายังต้องการให้ออฟเซ็ตนั้นเรียบโดยที่ความคล้ายคลึงกันของบล็อกบอกว่าไม่มีอะไรเกี่ยวกับออฟเซ็ต (เช่นตามเส้นตรงหรือในพื้นหลังสีขาว)
ดังนั้นเราจึงตั้งค่าคำศัพท์พลังงานที่สองเพื่อความราบรื่น:
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
เป็นน้ำหนักสัมพัทธ์พลังงานเรียบที่ได้รับในความสัมพันธ์กับระยะพลังงานจับคู่ภาพ ผลลัพธ์เหล่านี้มีน้ำหนักต่างกัน:
การปรับปรุงที่เป็นไปได้:
- อย่างที่ฉันบอกให้ทำการลงทะเบียนอย่างเข้มงวดก่อน ด้วยพื้นหลังสีขาวการลงทะเบียนตามช่วงเวลาของภาพอย่างง่ายควรทำงานได้ดี
- นี่เป็นเพียงขั้นตอนเดียว คุณสามารถใช้ออฟเซ็ตที่คุณพบในขั้นตอนเดียวและปรับปรุงในขั้นตอนที่สองอาจมีหน้าต่างค้นหาที่เล็กกว่าหรือขนาดบล็อกเล็กกว่า
- ฉันได้อ่านบทความที่พวกเขาทำสิ่งนี้โดยไม่มีบล็อกเลย แต่ปรับออฟเซตต่อพิกเซล
- ลองฟังก์ชั่นความนุ่มนวลที่แตกต่างกัน