我还不确定这是否正确,但这是我的第一次尝试。
private Mat preproc_img(Mat faceMat)
{
MatOfFloat hist = new MatOfFloat();
Cv2.CalcHist(new[] { faceMat }, new[] { 0 }, null, hist, 1, new[] { 256 }, new float[][] { new float[] { 0, 256 } });
Mat cdf = cumsum(hist);
cdf = cdf * (2.0 / cdf.At<float>(cdf.Rows - 1, 0)) - 1.0; // normalize
var cdfidx = cdf.GetGenericIndexer<float>();
Mat img_eq = EqualizeHist(faceMat, cdfidx);
Mat diff = (img_eq.Reshape(0, 64 * 64) - (A * (A_pinv * img_eq.Reshape(0, 64 * 64))));
var std = Math.Sqrt(diff.Dot(diff) / 64 / 64);
if (std > 1e-6)
diff = diff / std;
return diff.Reshape(0, 64);
}
private static Mat EqualizeHist(Mat faceMat, Mat.Indexer<float> cdfidx)
{
var img_eq = new Mat();
faceMat.ConvertTo(img_eq, MatType.CV_32FC1);
var idx = img_eq.GetGenericIndexer<float>();
for (var r = 0; r < img_eq.Rows; r++)
{
for (var c = 0; c < img_eq.Cols; c++)
{
idx[r, c] = cdfidx[(int)idx[r, c], 0];
}
}
return img_eq;
}
private static MatOfFloat cumsum(MatOfFloat hist)
{
var cdf = hist.Clone();
var indexer = cdf.GetIndexer();
var cumsum = 0.0f;
for (var i = 0; i < hist.Rows; i++)
{
cumsum += indexer[i, 0];
indexer[i,0] = cumsum;
}
return cdf;
}
public void initializeA()
{
MatOfInt X = new MatOfInt();
MatOfInt Y = new MatOfInt();
meshgrid(new MatOfInt(new int[] {1,64 },Enumerable.Range(0,64).ToArray()), new MatOfInt(new int[] { 1, 64 }, Enumerable.Range(0, 64).ToArray()), X, Y);
X = X.Reshape(1);
Y = Y.Reshape(1);
Console.WriteLine(X);
Console.WriteLine(Y);
A = new Mat();
A.PushBack(Mat.Ones(1, X.Cols,MatType.CV_32SC1));
A.PushBack(X);
A.PushBack(Y);
A = A.T();
A_pinv = A.Clone();
A.ConvertTo(A, MatType.CV_32FC1);
Cv2.Invert(A, A_pinv,DecompTypes.SVD);
}