আমি যেমন মন্তব্যগুলিতে বলেছি, মেডিকেল ইমেজ নিবন্ধকরণ এমন একটি বিষয় যা প্রচুর গবেষণা উপলব্ধ এবং আমি কোনও বিশেষজ্ঞ নই। আমি যা পড়েছি তা থেকে, সাধারণভাবে ব্যবহৃত মূল ধারণাটি হ'ল দুটি চিত্রের মধ্যে একটি ম্যাপিং সংজ্ঞায়িত করা (আপনার ক্ষেত্রে কোনও চিত্র এবং এর আয়না চিত্র), তারপরে মসৃণতার জন্য এবং ম্যাপিং প্রয়োগ করা থাকলে চিত্রের মিলের জন্য শক্তির শর্তাদি সংজ্ঞায়িত করা এবং অবশেষে মানক (বা কখনও কখনও অ্যাপ্লিকেশন-নির্দিষ্ট) অপ্টিমাইজেশান কৌশল ব্যবহার করে এই ম্যাপিংটিকে অনুকূলিত করুন।
এটি প্রকাশের জন্য আমি ম্যাথমেটিকায় একটি দ্রুত অ্যালগরিদম হ্যাক করেছি। এটি কোনও অ্যালগরিদম নয় যা আপনার চিকিত্সা অ্যাপ্লিকেশনটিতে ব্যবহার করা উচিত, কেবলমাত্র প্রাথমিক ধারণাগুলির একটি প্রদর্শনী।
প্রথমে, আমি আপনার চিত্রটি লোড করছি, এটি আয়না করব এবং এই চিত্রগুলি সামান্য ব্লকে বিভক্ত করব:
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
অফসেটগুলি প্রয়োগ করে মূল চিত্র এবং মিরর করা চিত্রের মধ্যে স্কোয়ার্ড ইউক্যালিডিয়ান পার্থক্যটি প্রায় অনুমান করে।
এই শক্তির একা অপ্টিমাইজ করা খারাপ ফলাফল দিতে পারে (যদি তা একেবারেই রূপান্তরিত হয়)। আমরা অফসেটগুলি মসৃণ করতে চাই, যেখানে ব্লকটির মিলটি অফসেট সম্পর্কে কিছুই না বলে (উদাহরণস্বরূপ একটি সরলরেখা বা সাদা ব্যাকগ্রাউন্ডে)।
সুতরাং আমরা মসৃণতার জন্য দ্বিতীয় শক্তি শব্দটি সেট আপ করেছি:
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]];
ভাগ্যক্রমে, সীমাবদ্ধ অপ্টিমাইজেশনটি গাণিতিকায় অন্তর্নির্মিত:
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
আপেক্ষিক ওজন স্নিগ্ধতা শক্তি ইমেজ ম্যাচ শক্তি মেয়াদ সম্পর্কিত পায়। এগুলি বিভিন্ন ওজনের জন্য ফলাফল:
সম্ভাব্য উন্নতি:
- আমি যেমন বলেছি, প্রথমে একটি অনমনীয় নিবন্ধকরণ করুন। একটি সাদা ব্যাকগ্রাউন্ডের সাথে, সাধারণ চিত্র মুহুর্ত-ভিত্তিক নিবন্ধকরণ ভাল কাজ করা উচিত।
- এটি কেবল একটি পদক্ষেপ। আপনি এক ধাপে পাওয়া অফসেটগুলি ব্যবহার করতে পারেন এবং দ্বিতীয় ধাপে সেগুলি উন্নত করতে পারেন, সম্ভবত কোনও ছোট অনুসন্ধান উইন্ডো বা ছোট ব্লকের আকারের সাহায্যে
- আমি নিবন্ধগুলি পড়েছি যেখানে তারা মোটেও ব্লক ছাড়াই এটি করে তবে পিক্সেল প্রতি অফসেটটি অনুকূলিত করে।
- বিভিন্ন মসৃণতা ফাংশন চেষ্টা করুন