图像离散傅里叶变化幅度谱检测---在条形码识别中的作用

来源:互联网 发布:淘宝省市区三级联动js 编辑:程序博客网 时间:2024/06/05 04:57

        图像的傅里叶变换是将时域空间信息转化为频域信息,图像的频谱图中携带着很多图像的信息,如规则文本的倾斜角度的信息,带有条形码的图像的倾斜角度信息。

以下代码是图像离散傅里叶变化幅度谱检测:

void FourierTransform(Mat InputImage, Mat &FourierTransImage,Mat &FourierImageAfterThreshold){// 定义图像Mat  imageGray;// 将图像三通道的图像转化为灰度图if (InputImage.channels() == 3){cvtColor(InputImage, imageGray, CV_RGB2GRAY);}else{imageGray = InputImage;}Mat imageGaussian;// 将图像进行高斯消除噪声,高斯消噪后的图像为imageGuussianGaussianBlur(imageGray, imageGaussian, Size(3, 3), 0);/*// 以下是用canndy算子的结果得到计算傅里叶变化的预处理图*/Mat canImage;// 将高斯消噪声后的图像进行canndy算子得到边缘Canny(imageGaussian, canImage, 100, 200);/*// 以下是用Sobel算子作为傅里叶变化的预处理图*///水平和垂直方向灰度图像的梯度和,使用Sobel算子,XY方向的梯度和为imageSobelOut      //Mat imageSobelX, imageSobelY, imageSobelOut;//Mat imageX16S, imageY16S;//Sobel(imageGaussian, imageX16S, CV_16S, 1, 0, 1, 1, 0, 4);//Sobel(imageGaussian, imageY16S, CV_16S, 0, 1, 1, 1, 0, 4);//convertScaleAbs(imageX16S, imageSobelX, 1, 0); // 使用线性变换转换输入数组元素成8位无符号整型//convertScaleAbs(imageY16S, imageSobelY, 1, 0);//imageSobelOut = imageSobelX + imageSobelY;/////////////////////////////////////////////////////////////////////////////////////////////以下是离散傅里叶变化/////////////////////////// 新定义一个Mat为srcImg为canImage或者imageSobelOut作为傅里叶变化的图Mat srcImg = canImage;// 设定padded为傅里叶变化扩充合适尺寸后的Mat,特定的宽高可以提高傅里叶运算效率    Mat padded;int optimalDFTWidth = getOptimalDFTSize(srcImg.rows);int optimalDFTHeight = getOptimalDFTSize(srcImg.cols);copyMakeBorder(srcImg, padded, 0, optimalDFTWidth - srcImg.rows, 0, optimalDFTHeight - srcImg.cols, BORDER_CONSTANT, Scalar::all(0));// planes[]是两通道的Mat,第一通道原图扩充后的Mat,尺寸大小和第一通道一样的Mat(其中值为0)Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat comImg;  //用来存储融合后的图像  merge(planes, 2, comImg); // 通道融合,融合成一个2通道的图像  dft(comImg, comImg); // 就地傅里叶变化split(comImg, planes); // 图像分割magnitude(planes[0], planes[1], planes[0]);Mat magMat = planes[0];  // magMat中将存放傅里叶变化的频谱图magMat += Scalar::all(1);log(magMat, magMat);     //对数变换,方便显示 magMat = magMat(Rect(0, 0, magMat.cols & -2, magMat.rows & -2));// 以下把傅里叶频谱图的四个角落移动到图像中心,再进行归一化(也可以先归一化再移动)  int cx = magMat.cols / 2;int cy = magMat.rows / 2;Mat q0(magMat, Rect(0, 0, cx, cy));Mat q1(magMat, Rect(0, cy, cx, cy));Mat q2(magMat, Rect(cx, cy, cx, cy));Mat q3(magMat, Rect(cx, 0, cx, cy));Mat tmp;q0.copyTo(tmp);q2.copyTo(q0);tmp.copyTo(q2);q1.copyTo(tmp);q3.copyTo(q1);tmp.copyTo(q3);normalize(magMat, magMat, 0, 1, CV_MINMAX); // magMat为离散傅里叶变化幅度谱图FourierTransImage = magMat.clone(); // 得到的是傅里叶变换幅度谱图Mat magImg(FourierTransImage.size(), CV_8UC1); // 定义一个与输入图像大小一样的MatFourierTransImage.convertTo(magImg, CV_8UC1, 255, 0);  // 将傅里叶归一化的Mat扩展至0-255threshold(magImg, magImg, 185, 255, CV_THRESH_BINARY);// 灰度阈值调节magImgFourierImageAfterThreshold = magImg.clone();}

得到的效果图像如下图所示:(可以用霍夫直线去拟合傅里叶变换后的灰度值图像)