• 4.5.实例应用


    4.5.1 导向滤波

    导向滤波能实现:双边滤波的边缘平滑;在检测到边缘附近

    应用:图像增强、HDR压缩、图像抠图以及图像去雾等

     1 #include <iostream>  
     2 #include "opencv2/core/core.hpp"    
     3 #include "opencv2/highgui/highgui.hpp"    
     4 #include "opencv2/imgproc/imgproc.hpp"      
     5 using namespace std;  
     6 using namespace cv;   
     7 // 导向滤波器 
     8 cv::Mat guidedfilter( Mat &srcImage, Mat &srcClone, int r, double eps )   
     9 {  
    10   // 转换源图像信息
    11   srcImage.convertTo(srcImage, CV_64FC1);      
    12   srcClone.convertTo(srcClone, CV_64FC1);   
    13   int nRows = srcImage.rows;  
    14   int nCols = srcImage.cols;   
    15   cv::Mat boxResult; 
    16   // 步骤一: 计算均值
    17   cv::boxFilter(cv::Mat::ones(nRows, nCols, srcImage.type()),
    18       boxResult, CV_64FC1, cv::Size(r, r));  
    19   // 生成导向均值mean_I    
    20   cv::Mat mean_I;  
    21   cv::boxFilter(srcImage, mean_I, CV_64FC1, cv::Size(r, r));   
    22   // 生成原始均值mean_p   
    23   cv::Mat mean_p;  
    24   cv::boxFilter(srcClone, mean_p, CV_64FC1, cv::Size(r, r)); 
    25   // 生成互相关均值mean_Ip 
    26   cv::Mat mean_Ip;  
    27   cv::boxFilter(srcImage.mul(srcClone), mean_Ip, 
    28       CV_64FC1, cv::Size(r, r));   
    29   cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p); 
    30   // 生成自相关均值mean_II 
    31   cv::Mat mean_II;  
    32   cv::boxFilter(srcImage.mul(srcImage), mean_II, CV_64FC1, cv::Size(r, r)); 
    33   // 步骤二:计算相关系数   
    34   cv::Mat var_I = mean_II - mean_I.mul(mean_I); 
    35   cv::Mat var_Ip = mean_Ip - mean_I.mul(mean_p); 
    36   // 步骤三:计算参数系数a,b 
    37   cv::Mat a = cov_Ip/(var_I + eps);    
    38   cv::Mat b = mean_p - a.mul(mean_I);  
    39   // 步骤四:计算系数a,b均值    
    40   cv::Mat mean_a;  
    41   cv::boxFilter(a, mean_a, CV_64FC1, cv::Size(r, r));  
    42   mean_a = mean_a / boxResult;     
    43   cv::Mat mean_b;  
    44   cv::boxFilter(b, mean_b, CV_64FC1, cv::Size(r, r));  
    45   mean_b = mean_b / boxResult;   
    46   //步骤五:生成输出矩阵 
    47   cv::Mat resultMat = mean_a.mul(srcImage) + mean_b;  
    48   return resultMat;  
    49 }    
    50 int main()  
    51 {    
    52     cv::Mat srcImage = cv::imread("..\images\flower3.jpg");
    53     if(srcImage.empty())
    54           return-1;
    55     cv::Mat srcGray(srcImage.size(),CV_8UC1);  
    56     cvtColor(srcImage,srcGray,CV_BGR2GRAY); 
    57     // 通道分离 
    58     vector<Mat> vSrcImage, vResultImage;  
    59     split(srcImage,vSrcImage);
    60     Mat resultMat;      
    61     for(int i=0; i < 3; i++)    
    62     {    
    63         // 分通道转换成浮点型数据
    64         Mat tempImage ; 
    65         vSrcImage[i].convertTo(tempImage, CV_64FC1,1.0/255.0);  
    66         Mat p = tempImage.clone();
    67         // 分别进行导向滤波       
    68         Mat resultImage = guidedfilter(tempImage, p, 4, 0.01);  
    69         vResultImage.push_back(resultImage);        
    70     } 
    71     // 通道结果合并   
    72     merge(vResultImage,resultMat);  
    73     cv::imshow("srcImage", srcImage);  
    74     cv::imshow("resultMat", resultMat);  
    75     cv::waitKey(0);    
    76     return 0;  
    77 }
    View Code

    第1张图片:

    参考链接:https://blog.csdn.net/gone_huilin/article/details/53223488

    第2张图片:

     1 //////https://blog.csdn.net/qq_34784753/article/details/70229009?locationNum=12&fps=1
     2 #include <iostream>
     3 #include <opencv2corecore.hpp>
     4 #include <opencv2highguihighgui.hpp>
     5 #include <opencv2imgprocimgproc.hpp>
     6 
     7 using namespace cv;
     8 using namespace std;
     9 
    10 //导向滤波器
    11 Mat guidedfilter(Mat &srcImage, Mat &srcClone, int r, double eps);
    12 
    13 int main()
    14 {
    15     Mat srcImage = imread("D:\小狗狗.jpg");
    16     if (srcImage.empty())
    17     {
    18         cout << "读入图片错误!" << endl;
    19         system("pause");
    20         return -1;
    21     }
    22     //进行通道分离
    23     //vector<Mat>vSrcImage, vResultImage;
    24     Mat vSrcImage[3];
    25     Mat vResultImage[3];
    26     split(srcImage, vSrcImage);
    27     Mat resultMat;
    28     for (int i = 0; i < 3; i++)
    29     {
    30         //分通道转换成浮点型数据
    31         Mat tempImage;
    32         vSrcImage[i].convertTo(tempImage, CV_64FC1, 1.0 / 255.0);
    33         Mat p = tempImage.clone();
    34         //分别进行导向滤波
    35         Mat resultImage = guidedfilter(tempImage, p, 4, 0.01);
    36         //vResultImage.push_back(resultImage);
    37         vResultImage[i] = resultImage.clone();
    38     }
    39     //通道结果合并
    40     //merge(vResultImage, resultMat);
    41     merge(vResultImage, 3, resultMat);
    42     imshow("原图像", srcImage);
    43     imshow("导向滤波后图像", resultMat);
    44     waitKey(0);
    45     return 0;
    46 }
    47 
    48 Mat guidedfilter(Mat &srcImage, Mat &srcClone, int r, double eps)
    49 {
    50     //转换源图像信息
    51     srcImage.convertTo(srcImage, CV_64FC1);
    52     srcClone.convertTo(srcClone, CV_64FC1);
    53     int NumRows = srcImage.rows;
    54     int NumCols = srcImage.cols;
    55     Mat boxResult;
    56 
    57     //下面按照步骤进行导向滤波操作
    58     /////////////////////////////////////////////////////////////
    59     //步骤一:计算均值
    60     boxFilter(Mat::ones(NumRows, NumCols, srcImage.type()),
    61         boxResult, CV_64FC1, Size(r, r));
    62     //生成导向均值mean_I
    63     Mat mean_I;
    64     boxFilter(srcImage, mean_I, CV_64FC1, Size(r, r));
    65     //生成原始均值mean_P
    66     Mat mean_P;
    67     boxFilter(srcClone, mean_P, CV_64FC1, Size(r, r));
    68     //生成互相关均值mean_IP
    69     Mat mean_IP;
    70     boxFilter(srcImage.mul(srcClone), mean_IP,
    71         CV_64FC1, Size(r, r));
    72     Mat cov_IP = mean_IP - mean_I.mul(mean_P);
    73     //生成自相关均值mean_II
    74     Mat mean_II;
    75     //应用盒滤波计算相关均值
    76     boxFilter(srcImage.mul(srcImage), mean_II, CV_64FC1, Size(r, r));
    77     //步骤二:计算相关系数
    78     Mat var_I = mean_II - mean_I.mul(mean_I);
    79     Mat var_IP = mean_IP - mean_I.mul(mean_P);
    80     //步骤三:计算参数系数a,b
    81     Mat a = cov_IP / (var_I + eps);
    82     Mat b = mean_P = a.mul(mean_I);
    83     //步骤四:计算系数a,b的均值
    84     Mat mean_a;
    85     boxFilter(a, mean_a, CV_64FC1, Size(r, r));
    86     mean_a = mean_a / boxResult;
    87     Mat mean_b;
    88     boxFilter(b, mean_b, CV_64FC1, Size(r, r));
    89     mean_b = mean_b / boxResult;
    90     //步骤五:生成输出矩阵
    91     Mat resultMat = mean_a.mul(srcImage) + mean_b;
    92     return resultMat;
    93 }
    View Code

    https://blog.csdn.net/qq_34784753/article/details/70229009?locationNum=12&fps=1 

    https://blog.csdn.net/kuweicai/article/details/78385871 

    https://blog.csdn.net/baimafujinji/article/details/74750283

    https://blog.csdn.net/huixingshao/article/details/42834939

    4.5.2 图像污点修复

    图像修补就是使用坏点周围的像素取代坏点,这样它看起来和周围像素就比较像了。

     1 //////https://blog.csdn.net/hb707934728/article/details/51980304?locationNum=8&fps=1
     2 //////运行程序出现2个窗口:原始图参考和原始图,在原始图窗口绘制污点完成后,按下按键1触发修复,后显示在修补后的效果图窗口
     3 //////terminal的提示非常棒!
     4 #include "opencv2/highgui/highgui.hpp"
     5 #include "opencv2/imgproc/imgproc.hpp"
     6 #include "opencv2/photo/photo.hpp"
     7 #include <iostream>
     8 using namespace cv;
     9 using namespace std;
    10 
    11 
    12 //-----------------------------------【宏定义部分】-------------------------------------------- 
    13 //  描述:定义一些辅助宏 
    14 //----------------------------------------------------------------------------------------------
    15 #define WINDOW_NAME0 "【原始图参考】"        //为窗口标题定义的宏 
    16 #define WINDOW_NAME1 "【原始图】"        //为窗口标题定义的宏 
    17 #define WINDOW_NAME2 "【修补后的效果图】"        //为窗口标题定义的宏 
    18 
    19 
    20 //-----------------------------------【全局变量声明部分】--------------------------------------
    21 //          描述:全局变量声明
    22 //-----------------------------------------------------------------------------------------------
    23 Mat srcImage0, srcImage1, inpaintMask;
    24 Point previousPoint(-1, -1);//原来的点坐标
    25 
    26 
    27                             //-----------------------------------【ShowHelpText( )函数】----------------------------------
    28                             //          描述:输出一些帮助信息
    29                             //----------------------------------------------------------------------------------------------
    30 static void ShowHelpText()
    31 {
    32 
    33     //输出一些帮助信息
    34     printf("
    
    
    	欢迎来到【图像修复】示例程序~
    ");
    35     printf("
    	请在进行图像修复操作之前,在【原始图】窗口中进行适量的绘制"
    36         "
    
    	按键操作说明: 
    
    "
    37         "		【鼠标左键】-在图像上绘制白色线条
    
    "
    38         "		键盘按键【ESC】- 退出程序
    
    "
    39         "		键盘按键【1】或【SPACE】-进行图像修复操作 
    
    ");
    40 }
    41 
    42 
    43 //-----------------------------------【On_Mouse( )函数】--------------------------------
    44 //          描述:响应鼠标消息的回调函数
    45 //----------------------------------------------------------------------------------------------
    46 static void On_Mouse(int event, int x, int y, int flags, void*)
    47 {
    48     //鼠标左键弹起消息
    49     if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))
    50         previousPoint = Point(-1, -1);
    51     //鼠标左键按下消息
    52     else if (event == CV_EVENT_LBUTTONDOWN)
    53         previousPoint = Point(x, y);
    54     //鼠标按下并移动,进行绘制
    55     else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
    56     {
    57         Point pt(x, y);
    58         if (previousPoint.x < 0)
    59             previousPoint = pt;
    60         //绘制白色线条
    61         line(inpaintMask, previousPoint, pt, Scalar::all(255), 5, 8, 0);
    62         line(srcImage1, previousPoint, pt, Scalar::all(255), 5, 8, 0);
    63         previousPoint = pt;
    64         imshow(WINDOW_NAME1, srcImage1);
    65     }
    66 }
    View Code

    绘制污点图:

    修复后图:

     1 ///////https://blog.csdn.net/dcrmg/article/details/53792061
     2 //////全区域阈值处理+Mask膨胀处理
     3 #include <imgprocimgproc.hpp>
     4 #include <highguihighgui.hpp>
     5 #include <photophoto.hpp>
     6 
     7 using namespace cv;
     8 
     9 int main()
    10 {
    11     Mat imageSource = imread("D:\图像污点修复.jpg");
    12     if (!imageSource.data)
    13     {
    14         return -1;
    15     }
    16     imshow("原图", imageSource);
    17     Mat imageGray;
    18     //转换为灰度图
    19     cvtColor(imageSource, imageGray, CV_RGB2GRAY, 0);
    20     Mat imageMask = Mat(imageSource.size(), CV_8UC1, Scalar::all(0));
    21 
    22     //通过阈值处理生成Mask
    23     threshold(imageGray, imageMask, 240, 255, CV_THRESH_BINARY);
    24     Mat Kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    25     //对Mask膨胀处理,增加Mask面积
    26     dilate(imageMask, imageMask, Kernel);
    27 
    28     //图像修复
    29     inpaint(imageSource, imageMask, imageSource, 5, INPAINT_TELEA);
    30     imshow("Mask", imageMask);
    31     imshow("修复后", imageSource);
    32     waitKey();
    33 }
    View Code

    原图: 

    处理过后:

    由于是图像全区域做阈值处理获得的掩码,图像上部分区域也被当做掩码对待,导致部分图像受损。

    方法二、鼠标框选区域+阈值处理+Mask膨胀处理

    方法三、鼠标划定整个区域作为修复对象

    参考:https://blog.csdn.net/dcrmg/article/details/53792061

     https://blog.csdn.net/chuhang_zhqr/article/details/51069183

    https://blog.csdn.net/qq_29540745/article/details/52563861

    https://blog.csdn.net/zhangjunp3/article/details/80059769

    4.5.3 旋转文本图像矫正

    利用傅里叶变换中时域与频域的变换关系实现旋转文本图像矫正。

    仿射变换需要获取图像的倾斜角度

    旋转文本图像的明显特征是存在分行间隔,当文本图像旋转时,其频域的频谱也会随之旋转。根据这一特征来计算文本图像的DFT变换,DFT变换的结果是

    霍夫变换、边缘检测等数字图像处理算法检测图像的旋转角度

    1、图像DFT尺寸转换

    2、DFT变换

    3、频域中心移动

    4、倾斜角检测

    5、仿射变换

      1 #include <opencv2/core/core.hpp>
      2 #include <opencv2/imgproc/imgproc.hpp>
      3 #include <opencv2/highgui/highgui.hpp>
      4 #include <iostream>
      5 using namespace cv;
      6 using namespace std;
      7 
      8 //傅里叶变化模块
      9 Mat DFT(Mat srcImage)
     10 {
     11     //1.转换位灰度图
     12     Mat srcGray;
     13     cvtColor(srcImage, srcGray, CV_BGR2GRAY);
     14 
     15     //2.将输入图像延扩到最佳的尺寸,边界用0填充
     16     int nRows = getOptimalDFTSize(srcGray.rows);
     17     int nCols = getOptimalDFTSize(srcGray.cols);
     18 
     19     Mat padded;
     20     //BORDER_CONSTANT是填充是常数的意思,填充的数是后面的0
     21     copyMakeBorder(srcGray, padded, 0, nRows - srcGray.rows, 0, nCols - srcGray.cols, BORDER_CONSTANT, Scalar::all(0));
     22 
     23     //3.为傅里叶变换的结果(实部与虚部)分别存储空间
     24     Mat planes[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };
     25     Mat complexI;
     26     //将planes数组组合合并成一个多通道的数组complexI
     27     merge(planes, 2, complexI);//将两个数组合并成一个多通道的数组
     28 
     29                                //4.进行离散傅里叶变换
     30     dft(complexI, complexI);
     31     //5.将复数转化为幅值
     32     // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I)
     33     split(complexI, planes);//将多通道数组complexI分解为几个单通道的数组
     34                             //magnitude(x,y,dst);dst=sqrt(x(I)^2+y(I)^2);
     35     magnitude(planes[0], planes[1], planes[0]);
     36     Mat magnitudeImage = planes[0].clone();//傅里叶变换的幅值矩阵
     37                                            //6.进行对数尺度缩放
     38     magnitudeImage += Scalar::all(1);//对幅值都加1
     39     log(magnitudeImage, magnitudeImage);
     40     //归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
     41     normalize(magnitudeImage, magnitudeImage, 0, 1, CV_MINMAX);
     42     //图像类型转换,为了下一步的霍夫直线检测做准备
     43     magnitudeImage.convertTo(magnitudeImage, CV_8UC1, 255, 0);
     44     imshow("magnitudeImage", magnitudeImage);
     45     //7.剪切与重分布幅度图象限
     46     //若有奇数行或者奇数列,进行频谱裁剪
     47     //magnitudeImage = magnitudeImage(Rect(0, 0, magnitudeImage.cols & -2, magnitudeImage.rows & -2));
     48     //重新排列傅里叶图像中的象限,使得原点位于图像中心
     49     int cx = magnitudeImage.cols / 2;
     50     int cy = magnitudeImage.rows / 2;
     51     Mat q0(magnitudeImage, Rect(0, 0, cx, cy));//ROI区域的左上
     52     Mat q1(magnitudeImage, Rect(cx, 0, cx, cy));//ROI区域的右上
     53     Mat q2(magnitudeImage, Rect(0, cy, cx, cy));//ROI区域的左下
     54     Mat q3(magnitudeImage, Rect(cx, cy, cx, cy));//ROI区域的右上
     55 
     56                                                  //交换象限(左上与右下进行交换)
     57     Mat temp;
     58     q0.copyTo(temp);
     59     q3.copyTo(q0);
     60     temp.copyTo(q3);
     61     //交换象限(右上与左下进行交换)
     62     q1.copyTo(temp);
     63     q2.copyTo(q1);
     64     temp.copyTo(q2);
     65     Point pt1, pt2;
     66     pt1.x = cx;
     67     pt2.x = cx;
     68     pt1.y = 0;
     69     pt2.y = magnitudeImage.rows;
     70 
     71     //往书上结果靠拢,去掉频域中心移动的横线和竖线,后面判断直线角度直接不需要
     72     //line(magnitudeImage, pt1, pt2, Scalar(0, 0, 0), 1, CV_AA);
     73 
     74     return magnitudeImage;
     75 }
     76 //倾斜角检测  返回检测到的倾斜角
     77 float AngleDetection(Mat srcImage)
     78 {
     79     int nRows = srcImage.rows;
     80     int nCols = srcImage.cols;
     81     Mat binaryMat;
     82     //对傅里叶变换之后的图像进行二值化处理
     83     //根据不同的图片情况可能需要调整这个固定阈值
     84     threshold(srcImage, binaryMat, 135, 255, CV_THRESH_BINARY);
     85     imshow("binaryMat", binaryMat);//显示二值图像
     86                                    //霍夫变换
     87     vector<Vec2f> lines;
     88     binaryMat.convertTo(binaryMat, CV_8UC1, 255, 0);
     89     //下面阈值可能也需要根据情况调整
     90     HoughLines(binaryMat, lines, 0.5, CV_PI / 180, 30, 0, 0);
     91     //检测线的个数
     92     cout << "lines.size:" << lines.size() << endl;
     93     //创建一张直线检测图形
     94     Mat houghMat(binaryMat.size(), CV_8UC3);
     95     //绘制线检测
     96     for (size_t i = 0; i < lines.size(); i++)
     97     {
     98         //根据直线参数表达式绘制相应的检测结果
     99         float rho = lines[i][0], theta = lines[i][1];
    100         Point pt1, pt2;
    101         double a = cos(theta), b = sin(theta);
    102         double x0 = a*rho, y0 = b*rho;
    103         pt1.x = cvRound(x0 + 1000 * (-b));
    104         pt1.y = cvRound(y0 + 1000 * (a));
    105         pt2.x = cvRound(x0 - 1000 * (-b));
    106         pt2.y = cvRound(y0 - 1000 * (a));
    107         line(houghMat, pt1, pt2, Scalar(255, 0, 0), 3, CV_AA);
    108     }
    109     //显示绘制的图
    110     imshow("houghMat", houghMat);
    111 
    112     float theta2 = 0;
    113     //检测线角度判断
    114     //因为文本检测的时候有三条直线,一条水平,一条垂直,还有一条就是我们需要的直线
    115     for (size_t i = 0; i < lines.size(); i++)
    116     {
    117         float ThetaTemp = lines[i][1] * 180 / CV_PI;
    118         //找出我们需要的那条直线就退出循环
    119         if (ThetaTemp > 0 && ThetaTemp < 90)
    120         {
    121             theta2 = ThetaTemp;
    122             break;
    123         }
    124     }
    125     //角度转换
    126     float angelT = nRows*tan(theta2 / 180 * CV_PI) / nCols;
    127     theta2 = atan(angelT) * 180 / CV_PI;
    128     cout << "theta2:" << theta2 << endl;
    129     return theta2;
    130 }
    131 
    132 //旋转图像,可以使用仿射变换
    133 Mat RotIamge(Mat &srcImage, float Angle) //旋转角度然后返回一张旋转后的图像
    134 {
    135     //以图像的中心为原点求出原图中的四个角的坐标
    136     float SrcX1, SrcY1, SrcX2, SrcY2, SrcX3, SrcY3, SrcX4, SrcY4;
    137     //新图中四个角的坐标
    138     float DstX1, DstY1, DstX2, DstY2, DstX3, DstY3, DstX4, DstY4;
    139     //将角度转换位弧度
    140     float alpha = Angle*CV_PI / 180;
    141     //原图的宽高
    142     int Wold = srcImage.cols;
    143     int Hold = srcImage.rows;
    144 
    145     //假设原图的原点在原图的中心主要是为了求出新图的宽高
    146     //原图的四个角的坐标
    147     SrcX1 = (float)((-0.5)*Wold);
    148     SrcY1 = (float)((0.5)*Hold);
    149     SrcX2 = (float)((0.5)*Wold);
    150     SrcY2 = (float)((0.5)*Hold);
    151     SrcX3 = (float)((-0.5)*Wold);
    152     SrcY3 = (float)((-0.5)*Hold);
    153     SrcX4 = (float)((0.5)*Wold);
    154     SrcY4 = (float)((-0.5)*Hold);
    155     //求出cosa 和sina
    156     float cosa = cos(alpha);
    157     float sina = sin(alpha);
    158 
    159     //求出新图的四个角的坐标
    160     DstX1 = cosa*SrcX1 + sina*SrcY1;
    161     DstY1 = -sina*SrcX1 + cosa*SrcY1;
    162     DstX2 = cosa*SrcX2 + sina*SrcY2;
    163     DstY2 = -sina*SrcX2 + cosa*SrcY2;
    164     DstX3 = cosa*SrcX3 + sina*SrcY3;
    165     DstY3 = -sina*SrcX3 + cosa*SrcY3;
    166     DstX4 = cosa*SrcX4 + sina*SrcY4;
    167     DstY4 = -sina*SrcX4 + cosa*SrcY4;
    168 
    169     //计算新图的宽和高
    170     int Wnew = cvRound(max(abs(DstX4 - DstX1), abs(DstX3 - DstX2)));
    171     int Hnew = cvRound(max(abs(DstY4 - DstY1), abs(DstY3 - DstY2)));
    172 
    173     //计算矩阵中的两个常数
    174     float num1 = (float)(-0.5*Wnew*cosa - 0.5*Hnew*sina + 0.5*Wold);
    175     float num2 = (float)(0.5*Wnew*sina - 0.5*Hnew*cosa + 0.5*Hold);
    176     //创建一张新的大小的图
    177     Mat resultImage(Hnew, Wnew, srcImage.type());
    178     for (int i = 0; i < Hnew; i++) //rows
    179     {
    180         for (int j = 0; j < Wnew; j++)//cols
    181         {
    182             //求出新图中的像素在原图的位置
    183             int x = cvRound(i*cosa + j*sina + num1);
    184             int y = cvRound(-sina*i + j*cosa + num2);
    185             if ((x >= 0) && (x < Wold) && (y >= 0) && (y < Hold))//在原图中的范围
    186             {
    187                 resultImage.at<Vec3b>(i, j) = srcImage.at<Vec3b>(x, y);
    188             }
    189         }
    190     }
    191     return resultImage;
    192 }
    193 int main()
    194 {
    195 
    196     Mat srcImage = imread("D:\倾斜文本.jpg");
    197     if (!srcImage.data)
    198     {
    199         printf("could not load image...
    ");
    200         return -1;
    201     }
    202     //Point center(srcImage.cols / 2, srcImage.rows / 2);
    203     //srcImage = getRotationMatrix2D(center, 27, 1.0);
    204     imshow("srcImage", srcImage);
    205     //输出傅里叶变换之后的图形
    206     Mat DFTImage = DFT(srcImage);
    207     imshow("DFT", DFTImage);
    208     //求出傅里叶变换里面的倾斜角
    209     float theta = AngleDetection(DFTImage);
    210     Mat retultImage = RotIamge(srcImage, theta);
    211     imshow("res", retultImage);
    212     waitKey(0);
    213     return 0;
    214 }
    View Code

    参考:

    https://blog.csdn.net/linqianbi/article/details/78863839

    https://www.cnblogs.com/skyfsm/p/6902524.html

    https://blog.csdn.net/liumoude6/article/details/77688798

    http://lib.csdn.net/article/opencv/24201 

    https://blog.csdn.net/longwinyang/article/details/52789260

    https://blog.csdn.net/liyuanbhu/article/details/50099767

    http://lib.csdn.net/article/opencv/28857 

    https://blog.csdn.net/spw_1201/article/details/53608805

  • 相关阅读:
    dell服务器 bios界面
    windows server 常用功能(一)
    Windows server 2016 / Windows 10关于域管理员帐号权限不足的问题
    (转)Java并发编程:并发容器之CopyOnWriteArrayList
    (转)ThreadLocal
    (转)java volatile关键字
    (转)java fail-fast机制
    (转)java并发对象锁、类锁、私有锁
    (转)java synchronised关键字
    javascript array
  • 原文地址:https://www.cnblogs.com/thebreakofdawn/p/9502715.html
Copyright © 2020-2023  润新知