Я реализую алгоритм деконволюции (для изображений DIC) с OpenCVSharp (C # упаковка OpenCV). По некоторым причинам после того, как я использую алгоритм Cv2.Dft для deltaPhiXY (см. Ниже), действительная и мнимая часть преобразования Фурье всегда равна нулю; deltaPhiXY всегда находится в диапазоне от -pi / 2 до pi / 2, как и ожидалось (и обязательно). У вас есть подсказка, почему я не могу вычислить DFT на deltaPhiXY? Если кто-то интересуется математической теорией, это статья http://dare.uva.nl/document/2/3308
Действительно большое спасибо за любую помощь.
// deconvolve the frame
int deltaX = Session.Params.ParamsPreprocessing.DeltaX;
int deltaY = Session.Params.ParamsPreprocessing.DeltaY;
float s = Session.Params.ParamsPreprocessing.S;
float sigma = Session.Params.ParamsPreprocessing.Sigma;
if (deltaX != 0 && deltaY != 0 && s != 0 && sigma != 0)
{
// initialize deconvolution variables
MatOfDouble
deltaPhiXY = new MatOfDouble(frame.Size()),
realW = new MatOfDouble(frame.Size(), 0),
imgW = new MatOfDouble(frame.Size());
frame.ConvertTo(frame, MatType.CV_64FC1);
MatIndexer<double>
indexerFrame = (new MatOfDouble(frame)).GetIndexer(),
indexerDeltaPhiXY = deltaPhiXY.GetIndexer(),
indexerImgW = imgW.GetIndexer();
double
IMax,
IMin;
frame.MinMaxIdx(out IMin, out IMax);
double
phi = 0,
G = 0,
SN = 0,
w = 0;
// build deltaPhi (in x, y) and W (in u, v)
for(int row = 0; row < frame.Rows; row++)
{
for(int col = 0; col < frame.Cols; col++)
{
// set deltaPhi
phi =
Math.Acos
(
(2 * (indexerFrame[row, col] - IMin)
/
(IMax - IMin))
- 1
)
- Math.PI / 2;
indexerDeltaPhiXY[row, col] =
phi;// set complex G in u, v
G =
2*Math.Sin(Math.PI * (row * deltaX + col * deltaY));
// set SN in u, v (spectral distribution of the signal to noise ratio)
SN =
s * Math.Exp(-2 * Math.PI * Math.PI * sigma * sigma * (row * row + col * col));
// set W in u, v
w =
-G / (G * G + (1 / SN));
indexerImgW[row, col] =
w;
}
}
// build deltaPhi
Mat deltaPhi = new Mat();
Cv2.Dft(deltaPhiXY, deltaPhi, DftFlag2.Scale | DftFlag2.ComplexOutput); // here I had used other flags but the final result is always 0
// Cv2.Merge(new Mat[] { deltaPhiXY, new Mat(deltaPhiXY.Size(), MatType.CV_64FC1, Scalar.All(0)) }, deltaPhi);
// deltaPhi = deltaPhi.Dft();
Mat[] planesDeltaPhi = deltaPhi.Split();
Mat realDeltaPhi = planesDeltaPhi[0];
Mat imgDeltaPhi = planesDeltaPhi[1];
// get phi = W*deltaPhi (deconvolution)
Mat
realPhi = -imgW.Mul(imgDeltaPhi),
imgPhi = imgW.Mul(realDeltaPhi);
// get deconvolved frame (inverse Fourier's transform)
Cv2.Merge(new Mat[] { realPhi, imgPhi }, frame);
frame = frame.Dft(DftFlag2.Inverse | DftFlag2.RealOutput);
frame = frame.Normalize(IMin, IMax, NormType.MinMax, MatType.CV_32FC1);
}
Исправлена,
по какой-то причине необходимо использовать DFT (и IDFT) для переменной Mat (по крайней мере, для приведенного выше кода), чтобы использовать этот фрагмент:
double
min,
max;
toTransform.MinMaxIdx(out min, out max);
toTransform = toTransform.Normalize(0, int.MaxValue, NormType.MinMax, MatType.CV_32SC1);
toTransform = toTransform.Normalize(min, max, NormType.MinMax, MatType.CV_64FC1);
Я не знаю, связана ли проблема со значениями в моих переменных Mat или с библиотекой OpenCV, но этот обходной путь работает (по крайней мере) в моем случае.