Radon算法
Radon(拉东)算法是一种通过定方向投影叠加,找到最大投影值时角度,从而确定图像倾斜角度的算法。具体过程如图所示
图1 Radon变换算法
Radon计算示例
对于纹理方向明显的图像,如图2所示,可以通过Radon变换求取倾斜角度。
图2 带求倾斜角度图像
具体步骤如下:
1、图像傅里叶变换
采用Cv2.Dft函数,对图2进行傅里叶变换,变换后的图像如图3所示:
图3 二值化后的傅里叶变换图像
从上面图像可以看到,傅里叶变化图像3方向,与图像2纹理方向呈现垂直关系。我们只要求出来图3的倾斜方向,即可求出来实际图像的倾斜方向。
对于尺寸较大的图像,可采取金字塔下采样方式,将图像进行压缩,以减少Radon计算的时间。
2、金字塔下采样
应用Cv2.PyrDown进行金字塔下采样,减少图像3的尺寸。
while (pyrMat.Width > 100 || pyrMat.Height > 100)
{
Cv2.PyrDown(pyrMat, pyrMat, new OpenCvSharp.Size(tempMat.Cols * 0.5, tempMat.Rows * 0.5));
}
压缩后的图像如下图4所示。
图4 金字塔下采样的图片
3、Radon变换
根据Radon变换原理,编写Radon变换代码,伪代码如下所示:
for (int t = 0; t < 180; t++)
{
double tempAngle = t * Math.PI / angle;
float[,] R = new float[3, 3] {{(float)Math.Cos(tempAngle), (float)Math.Sin(tempAngle), 0 },
{ -(float)Math.Sin(tempAngle), (float)Math.Cos(tempAngle), 0},
{ 0, 0, 1 } };
Mat mR = new Mat(3, 3, MatType.CV_32FC1, R);
Mat rotation = m1 * mR * m0;
Mat rotated = new Mat();
Cv2.WarpPerspective(dst, rotated, rotation, new OpenCvSharp.Size(dst.Rows, dst.Cols), InterpolationFlags.WarpInverseMap);
rotated.ConvertTo(rotated, MatType.CV_8UC1);
//Cv2.ImShow("test3", rotated);
rotated.ConvertTo(rotated, MatType.CV_32FC1);
double Sum = 0;
List<float> arrMaxCol = new List<float>();
for (int j = 0; j < rotated.Cols; j++)
{
/*正文下载链接中有详细代码*/
}
arrMaxAngle.Add(arrMaxCol.Max());
}
var maxSum = arrMaxAngle.Max();
var maxInd = arrMaxAngle.IndexOf(maxSum);
return maxInd-90;
最终计算的倾斜角度如下图5程序界面所示。
图5 最终计算结果
Radon变换的下载链接如下:
https://download.csdn.net/download/qq_20660115/88550141