承接上一篇用python实现图像自卷积功能:Python图像自卷积消除纹理
由于项目原因,需要在.NET的项目中来实现功能,emgucv是opencv的.ENT版本,是对opencv的集成,但有些功能实现起来并没有原生的opencv方便。这里简单讲一下emgucv中的主要图像对象,Image<TColor, TDepth>,Mat,矩阵Matrix,接下来在代码中会用到。
int coreSize = Convert.ToInt32(barSelfCov.EditValue);//获取核大小
int cycle = 10;//自定义循环次数
Random rd = new Random();
float[,] allGrayPix = new float[cycle, coreSize * coreSize];//所有通过循环得到的核,循环次数*核面积
float[] avgFloat = new float[coreSize * coreSize];//核中每个像素的平均像素值,一维数组
float[,] result = new float[coreSize, coreSize];//核中每个像素的平均像素值,二维数组
for (int c = 0; c < cycle; c++)
{
Rectangle rec = new Rectangle(rd.Next(256 - coreSize), rd.Next(256 - coreSize), coreSize, coreSize);
Mat rdMat = new Mat(imageTempGray, rec);
Image<Gray, byte> rdImage = rdMat.ToImage<Gray, byte>();
for (int i = 0; i < rdMat.Width; i++)
{
for (int j = 0; j < rdMat.Height; j++)
{
allGrayPix[c, i * coreSize + j] = (float)rdImage[i, j].Intensity;//像素的值(灰度)
}
}
}
//转换成矩阵来获取每列的平均值
Matrix<Single> m = new Matrix<Single>(allGrayPix);
for (int i = 0; i < coreSize * coreSize; i++)
{
Matrix<float> cols = m.GetCol(i);
avgFloat[i] = (float)CvInvoke.Mean(cols).V0;
}
//一维数组转二维数组
for (int x = 0; x < coreSize; x++)
{
for (int y = 0; y < coreSize; y++)
{
result[x, y] = avgFloat[x * coreSize + y];
}
}
Matrix<float> AffineOfferMat = new Matrix<float>(result);
AffineOfferMat = AffineOfferMat / AffineOfferMat.Sum;//加权平均
Image<Gray, float> imageCovSelf = imageTempGray.ToImage<Gray,byte>().Convolution(new ConvolutionKernelF(AffineOfferMat.Data));
imageTempFilter = imageCovSelf.Convert<Gray, byte>().Mat.Clone();
代码中用到很多for循环,可能优化不是很好,用stopwatch看用时基本在30毫秒左右,对比其他空间域平滑的卷积几毫秒还是要慢不少,还需要想办法优化。