中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OpenCV實現圖像校正功能

發布時間:2020-09-20 05:34:03 來源:腳本之家 閱讀:257 作者:基科菜雞 欄目:編程語言

一、 需求分析

首先是需求:

1、利用 OpenCV 里面的仿射變換函 數實現對圖像進行一些基本的變換,如平移、旋轉、縮放
2、學習透視變換原理,對一個矩形進行透視變換,并將變換結果繪制出來。先調用 OpenCV 函數實現透視變換,自己編寫代碼實現透視變換。
3、識別一張傾斜拍攝的紙張,找出輪廓,提取出該紙張的位置
4、 假設你已通過圖像處理的算法找到發生形變的紙張的位置,那么對這個傾斜 紙張進行變換,得到紙張的垂直視圖,實現文檔校準。

然后是分析:

1、首先要調用OpenCV的函數對圖像進行平移、旋轉、縮放變換,然后要進行仿射變換和透視變換。
2、編程實現仿射變換和透視變換,注意到仿射變換是透視變換的一種,因此只需實現透視變換
3、 實現文檔校準:

(1)濾波。考慮到文檔中的字(噪點),同時采用均值濾波和閉運算濾波。
(2)邊緣提取。利用庫函數提取邊緣信息
(3)邊緣識別。利用經典霍夫變換,獲得邊界方程,并且計算出文檔的四個角的坐標
(4)透視變換。調用庫函數,實現文檔校準

5、由于前三個需求與最后一個需求的源碼放在同一個工程中顯得不合適,因此,我將前三個需求的代碼和注釋放在了工程:作業2_2中,開發環境是win10 vs2017,openCV3.43

二、 實現

注意:

以下的函數全部寫在標頭.h文件中,要在在main中調用標頭.h文件中的函數才能完成功能
還有就是圖片輸入的路徑要改好。

1、工程:作業2_2的實現

(1)調用OpenCV內的函數,編寫了一個main_transform函數,在主函數調用它,輸入圖片后,同時將圖片縮小、平移、旋轉、透視和仿射變換,并且將圖片展示和保存下來(實際上后來openCV的仿射、透視我注釋掉了,不用它自帶的函數了)
都是直接調用函數,沒什么好說的。

下面分別是旋轉、透視、平移、縮小、仿射的效果圖:

(2)手動實現仿射、透視變換函數 toushibianhuan和toushibianhuan_gai_fangshebianhuan,并在main_transform中調用他們。

透視變換實現:

注意到仿射變換是透視變換的特殊情況,因此只要實現了透視就可以實現仿射。

透視函數的實現:

首先使用getPerspectiveTransform來獲取變換矩陣,然后看透視函數

toushibianhuan函數需要三個輸入參數:

  • 第一個參數:透視變換輸入的圖像矩陣,Mat
  • 第二個參數:輸出圖像容器矩陣,Mat
  • 第三個參數:變換矩陣,Mat

進入函數后,首先定義出一個位置矩陣position_maxtri用以刻畫變換前圖像的位置,利用矩陣元素積,乘以變換矩陣后算出變換后的四個角的位置矩陣。

用Max、Min函數計算出圖像最高點、最低點,進而算出圖像的高和寬

然后,重點來了,定義、更新計算出兩個重映射矩陣。Map1是從原圖的x—>新圖x的映射,Map2是從原圖y—>新圖y的映射。

/*-----------------------------------------------------------------------------------------------------------------
Copyright (C),2018---, HUST Liu
 File name: image_solve.h
 Author: 劉峻源 Version: 1 Date: 2018.10.3
 ------------------------------------------------------------------------------------------------------------------
 Description:
 文檔矯正項目.cpp的主要函數儲存在這里

 
-------  -----------   ------------  ------------   -----------  ---------
函數說明:comMatC用于連接矩陣
 toushibianhuan_gai_fangshebianhuan用于仿射變換
 toushibianhuan用于仿射變換
 main_transform 調用函數來處理圖像,包括平移、縮小、旋轉、仿射變換和透視變換
 input_solve 用以矯正文檔,包括打開圖像、濾波、提取邊緣、繪制邊緣、透視變換矯正文檔
--------------------------------------------------------------------------------
 Others:NONE
 Function List: comMatC、toushibianhuan、toushibianhuan_gai_fangshebianhuan、input_solve
 --------------------------------------------------------------------------------
 history: NONE

-------------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------
標準openCV開頭         --
引用頭文件和命名空間        --
------------------------------------------------------------------*/
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <imgproc.hpp>
using namespace std;
using namespace cv;

/*-------------------------------------------------------------------------------
Function: comMatC
 Description:上下連接矩陣,并輸出
 --------------------------------------------------------------------------------
 Calls:Create、copyTo
 Called By: main_transform
 Table Accessed: NONE
 Table Updated: NONE
 --------------------------------------------------------------------------------
 Input:
 第一個參數:上面的矩陣,Mat
 第二個參數:下面的矩陣,Mat
 第三個參數:連接后的輸出容器,Mat
 Output:輸出連接后的矩陣
 Return:輸出矩陣
 Others:列數不一致會報錯!
---------------------------------------------------------------------------------*/
Mat comMatC(Mat Matrix1, Mat Matrix2, Mat &MatrixCom)
{
 CV_Assert(Matrix1.cols == Matrix2.cols);
 MatrixCom.create(Matrix1.rows + Matrix2.rows, Matrix1.cols, Matrix1.type());
 Mat temp = MatrixCom.rowRange(0, Matrix1.rows);
 Matrix1.copyTo(temp);
 Mat temp1 = MatrixCom.rowRange(Matrix1.rows, Matrix1.rows + Matrix2.rows);
 Matrix2.copyTo(temp1);
 return MatrixCom;
}

/*--------------------------------------------------------------------------------
Function: toushibianhuan
 Description:實現透視變換功能 ,將input_image按tp_Transform_maxtri矩陣變換后輸出至另一圖像容器中
 -------------------------------------------------------------------------------
 Calls:max、min
 Called By:main_transform
 Table Accessed: NONE
 Table Updated: NONE
 ----------------------------------------------------------------------------------
 Input:
 第一個參數:透視變換輸入的圖像矩陣,Mat
 第二個參數:輸出圖像容器矩陣,Mat
 第三個參數:變換矩陣,Mat
 Output:無返回值。在控制臺上打印出原圖的位置矩陣、變換后的圖像坐標矩陣、變換矩陣
 Return:NONE
 Others:NONE
-----------------------------------------------------------------*/
void toushibianhuan(Mat input_image, Mat &output, Mat tp_Translater_maxtri)
{
 int qiu_max_flag;
 int j;
 int i;
 //定義頂點位置矩陣
 Mat position_maxtri(3, 4, CV_64FC1, Scalar(1));
 position_maxtri.at < double >(0, 0) = 0;
 position_maxtri.at < double >(1, 0) = 0;
 position_maxtri.at < double >(1, 1) = 0;
 position_maxtri.at < double >(0, 2) = 0;
 position_maxtri.at < double >(1, 2) = input_image.rows;
 position_maxtri.at < double >(0, 3) = input_image.cols;
 position_maxtri.at < double >(1, 3) = input_image.rows;
 position_maxtri.at < double >(0, 1) = input_image.cols;
 Mat new_corner = tp_Translater_maxtri * position_maxtri;
 //打印并監視三個矩陣
 cout << "coner_maxtri" << new_corner << ";" << endl << endl;
 cout << "pos_maxtri" << position_maxtri << ";" << endl << endl;
 cout << "T_maxtri" << tp_Translater_maxtri << ";" << endl << endl;
 //為了計算圖像高度,先初始化最高最低、最左最右點
 double max_kuan = new_corner.at < double >(0, 0) / new_corner.at < double >(2, 0);
 double min_kuan = new_corner.at < double >(0, 0) / new_corner.at < double >(2, 0);
 double max_gao = new_corner.at < double >(1, 0) / new_corner.at < double >(2, 0);
 double min_gao = new_corner.at < double >(1, 0) / new_corner.at < double >(2, 0);
 for (qiu_max_flag = 1; qiu_max_flag < 4; qiu_max_flag++)
 {
 max_kuan = max(max_kuan,
 new_corner.at < double >(0, qiu_max_flag) / new_corner.at < double >(2, qiu_max_flag));
 min_kuan = min(min_kuan,
 new_corner.at < double >(0, qiu_max_flag) / new_corner.at < double >(2, qiu_max_flag));
 max_gao = max(max_gao,
 new_corner.at < double >(1, qiu_max_flag) / new_corner.at < double >(2, qiu_max_flag));
 min_gao = min(min_gao,
 new_corner.at < double >(1, qiu_max_flag) / new_corner.at < double >(2, qiu_max_flag));
 }
 //創建向前映射矩陣 map1, map2
 output.create(int(max_gao - min_gao), int(max_kuan - min_kuan), input_image.type());
 Mat map1(output.size(), CV_32FC1);
 Mat map2(output.size(), CV_32FC1);
 Mat tp_point(3, 1, CV_32FC1, 1);
 Mat point(3, 1, CV_32FC1, 1);
 tp_Translater_maxtri.convertTo(tp_Translater_maxtri, CV_32FC1);
 Mat Translater_inv = tp_Translater_maxtri.inv();
 //核心步驟,將映射陣用矩陣乘法更新出來
 for (i = 0; i < output.rows; i++)
 {
 for (j = 0; j < output.cols; j++)
 {
 point.at<float>(0) = j + min_kuan;
 point.at<float>(1) = i + min_gao;
 tp_point = Translater_inv * point;
 map1.at<float>(i, j) = tp_point.at<float>(0) / tp_point.at<float>(2);
 map2.at<float>(i, j) = tp_point.at<float>(1) / tp_point.at<float>(2);
 }
 }

 remap(input_image, output, map1, map2, CV_INTER_LINEAR);
}

/*--------------------------------------------------------------------------------
Function: toushibianhuan_gai_fangshebianhuan
 Description:實現仿射變換功能 ,將input_image按Translater_maxtri矩陣變換后輸出至另一圖像容器中
 ------------------------------------------------------------------------------------
 Calls:comMatC、max、min
 Called By:main_transform
 Table Accessed: NONE
 Table Updated: NONE
 ------------------------------------------------------------------------------------
 Input:
 第一個參數:透視變換輸入的圖像矩陣,Mat
 第二個參數:輸出圖像矩陣,Mat
 第三個參數:變換矩陣,Mat
 Output:無返回值。在控制臺上打印出原圖的位置矩陣、變換后的圖像坐標矩陣、變換矩陣
 Return:NONE
 Others:NONE
-------------------------------------------------------------------------------*/
void toushibianhuan_gai_fangshebianhuan(Mat input_image, Mat &output, Mat Translater_maxtri)
{
 int width = 0;
 int height = 0;
 Mat tp_Translater_maxtri;
 Mat position_maxtri(3, 4, CV_64FC1, Scalar(1));
 Mat one_vector(1, 3, CV_64FC1, Scalar(0));
 one_vector.at<double>(0, 2) = 1.;
 comMatC(Translater_maxtri, one_vector, tp_Translater_maxtri);
 position_maxtri.at < double >(1, 1) = 0;
 position_maxtri.at < double >(0, 2) = 0;
 position_maxtri.at < double >(0, 0) = 0;
 position_maxtri.at < double >(1, 0) = 0;
 position_maxtri.at < double >(0, 3) = input_image.cols;
 position_maxtri.at < double >(1, 3) = input_image.rows;
 position_maxtri.at < double >(0, 1) = input_image.cols;
 position_maxtri.at < double >(1, 2) = input_image.rows;
 Mat new_corner = tp_Translater_maxtri * position_maxtri;
 cout << "coner_maxtri" << new_corner << ";" << endl << endl;
 cout << "pos_maxtri" << position_maxtri << ";" << endl << endl;
 cout << "T_maxtri" << tp_Translater_maxtri << ";" << endl << endl;
 double max_kuan = new_corner.at < double >(0, 0) / new_corner.at < double >(2, 0);
 double min_kuan = new_corner.at < double >(0, 0) / new_corner.at < double >(2, 0);
 double max_gao = new_corner.at < double >(1, 0) / new_corner.at < double >(2, 0);
 double min_gao = new_corner.at < double >(1, 0) / new_corner.at < double >(2, 0);
 for (int flag = 1; flag < 4; flag++)
 {
 max_kuan = max(max_kuan, new_corner.at < double >(0, flag) / new_corner.at < double >(2, flag));
 min_kuan = min(min_kuan, new_corner.at < double >(0, flag) / new_corner.at < double >(2, flag));
 max_gao = max(max_gao, new_corner.at < double >(1, flag) / new_corner.at < double >(2, flag));
 min_gao = min(min_gao, new_corner.at < double >(1, flag) / new_corner.at < double >(2, flag));
 }
 output.create(int(max_gao - min_gao), int(max_kuan - min_kuan), input_image.type());
 Mat map1(output.size(), CV_32FC1);
 Mat map2(output.size(), CV_32FC1);
 Mat tp_point(3, 1, CV_32FC1, 1);
 Mat point(3, 1, CV_32FC1, 1);
 tp_Translater_maxtri.convertTo(tp_Translater_maxtri, CV_32FC1);
 Mat Translater_inv = tp_Translater_maxtri.inv();
 for (int i = 0; i < output.rows; i++)
 {
 for (int j = 0; j < output.cols; j++)
 {
 point.at<float>(1) = i + min_gao;
 point.at<float>(0) = j + min_kuan;
 tp_point = Translater_inv * point;
 map1.at<float>(i, j) = tp_point.at<float>(0) / tp_point.at<float>(2);
 map2.at<float>(i, j) = tp_point.at<float>(1) / tp_point.at<float>(2);
 }
 }
 remap(input_image, output, map1, map2, CV_INTER_LINEAR);
}

/*------------------------------------------------------------------------------
Function: main_transform
 Description:實現縮小、平移、旋轉的仿射變換功能 ,加以展示且將圖片保存在當前工程目錄下
 ---------------------------------------------------------------------------
 Calls: resize、 warpAffine、 Size 、 Scalar 、getRotationMatrix2D、 namedWindow、
 toushibianhuan_gai_fangshebianhuan、 imshow、 imwrite、waitKey、printf、warpPerspective、fangshebianhuan
 Called By: main
 Table Accessed: NONE
 Table Updated: NONE
 --------------------------------------------------------------------------------
 Input:
 第一個參數:float類型的旋轉角度值(非弧度)
 第二個參數:向右平移的像素,int類型
 第三個參數:向下平移的像素,int類型
 第四個參數:讀取圖像路徑,const char類型
 第五個參數:x方向伸縮比例,float類型
 第六個參數:y方向伸縮比例,float類型
 Output:仿射變換、透視變換后的圖像保存于當前工程目錄下,各參數已經設置好,矯正效果不佳
 Return:無返回值
 Others:NONE
---------------------------------------------------------------------------*/
void main_transform(float angle, int right_translate, int down_translate,
 const char* road_read_image, float x_tobe, float y_tobe)
{
 Point2f input_image1[3] = { Point2f(50,50),Point2f(200,50),Point2f(50,200) };
 Point2f dst1[3] = { Point2f(0,100),Point2f(200,50),Point2f(180,300) };
 Point2f input_image[4] = { Point2f(100,50),Point2f(100,550),Point2f(350,50),Point2f(350,550) };
 Point2f dst[4] = { Point2f(100,50),Point2f(340,550),Point2f(350,80),Point2f(495,550) };
 Mat kernel2 = getPerspectiveTransform(input_image, dst);
 Mat kernel = getAffineTransform(input_image1, dst1);
 Mat one_vector(1, 3, CV_64FC1, Scalar(0));
 Mat Temp_kernel;
 one_vector.at<double>(0, 2) = 1.;
 comMatC(kernel, one_vector, Temp_kernel);
 float all_tobe = x_tobe / 2 + y_tobe / 2;
 Mat old_image = imread(road_read_image);
 Mat new_min_image;
 Mat new_translation_image;
 Mat rotate_image;
 Mat translater(2, 3, CV_32F, Scalar(0));
 Mat rotater;
 Mat fangshe_image;
 Mat toushi_image;
 vector<int> compression_params;
 resize(old_image, new_min_image, Size(), x_tobe, y_tobe, INTER_CUBIC);
 translater.at<float>(0, 0) = 1;
 translater.at<float>(1, 1) = 1;
 translater.at<float>(0, 2) = right_translate;
 translater.at<float>(1, 2) = down_translate;
 warpAffine(new_min_image, new_translation_image, translater,
 Size(new_min_image.cols*1.5, new_min_image.rows*1.5));
 Point rotate_center = Point(new_translation_image.cols / 3, new_translation_image.rows / 2);
 rotater = getRotationMatrix2D(rotate_center, angle, all_tobe);
 warpAffine(new_translation_image, rotate_image, rotater, Size(),
 INTER_CUBIC | CV_WARP_FILL_OUTLIERS, BORDER_CONSTANT, Scalar(0));
 //warpAffine(new_translation_image, fangshe_image, kernel, Size(new_translation_image.cols*1.5, new_translation_image.rows*1.5));
 //這是OpenCV自帶的仿射變換.........
 compression_params.push_back(IMWRITE_PNG_COMPRESSION);
 toushibianhuan_gai_fangshebianhuan(new_translation_image, fangshe_image, kernel);
 toushibianhuan(fangshe_image, toushi_image, kernel2);

 //warpPerspective(fangshe_image, toushi_image, kernel2, Size(new_translation_image.cols, new_translation_image.rows));
 //這是openCV的透視變換
 compression_params.push_back(9);
 namedWindow("new_min_image");
 imshow("new_min_image", new_min_image);
 imwrite("task2_1放縮.png", old_image, compression_params);
 namedWindow("new_translation_image");
 imshow("new_translation_image", new_translation_image);
 bool flags = imwrite("task2_1平移.png", new_translation_image, compression_params);
 namedWindow("rotate_image");
 imshow("rotate_image", rotate_image);
 imwrite("task2_1旋轉.png", rotate_image, compression_params);
 namedWindow("fangshe_image");
 imshow("fangshe_image", fangshe_image);
 imwrite("task2_1仿射.png", fangshe_image, compression_params);
 namedWindow("toushi_image");
 imshow("toushi_image", toushi_image);
 imwrite("task2_1透視.png", toushi_image, compression_params);
 printf("%d", flags);

}

/*----------------------------------------------------------------------------
Function: getCrossPoint
 Description:求兩直線的交點
 -----------------------------------------------------------------------------
 Calls: NONE
 Called By: input_solve
 Table Accessed: NONE
 Table Updated: NONE
 -----------------------------------------------------------------------------
 Input:
 第一個參數:由兩點表示的類型為Vec4i的直線A
 第二個參數:由兩點表示的類型為Vec4i的直線B
 Output:Point2f的點
 Return:Point2f的點
 Others:NONE
--------------------------------------------------------------------------------*/
Point2f getCrossPoint(Vec4i LineA, Vec4i LineB)
{
 double ka, kb;
 //求出LineA斜率
 ka = (double)(LineA[3] - LineA[1]) / (double)(LineA[2] - LineA[0]); 
 //求出LineB斜率
 kb = (double)(LineB[3] - LineB[1]) / (double)(LineB[2] - LineB[0]); 


 Point2f crossPoint;
 crossPoint.x = (ka*LineA[0] - LineA[1] - kb * LineB[0] + LineB[1]) / (ka - kb);
 crossPoint.y = (ka*kb*(LineA[0] - LineB[0]) + ka * LineB[1] - kb * LineA[1]) / (ka - kb);
 return crossPoint;
}

/*----------------------------------------------------------------------
Function: input_solve
 Description:用于打開圖像、濾波、提取邊緣、繪制邊緣、透視變換矯正文檔的函數。注意,本函數中圖像
 處理過程中的參數已經調整完畢
 ------------------------------------------------------------------------
 Calls: imread、resize、morphologyEx、blur、Canny、HoughLines、warpPerspective
 Called By: main
 Table Accessed: NONE
 Table Updated: NONE
 -------------------------------------------------------------------------
 Input:
 第一個參數:輸入圖像的路徑
 Output:經過文檔矯正后的圖像
 Return:NONE
 Others:矯正圖像保存于當前目錄下:
 "C:/Users/liujinyuan/source/repos/作業2_2/作業2_2/task2_2矯正.png"
---------------------------------------------------------------*/
void input_solve(const char* image_road)
{
 //定義保存圖像參數向量
 vector<int> compression_params;
 compression_params.push_back(IMWRITE_PNG_COMPRESSION);
 compression_params.push_back(9);
 //獲取閉運算濾波的核
 Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
 Mat new_min_image;
 Mat last_kernel;
 //獲取灰度圖
 Mat old_image = imread(image_road,0);
 vector<Vec2f>lines;
 vector<Vec2f>coners;
 vector<Vec4i>lines_2pt(10);
 Point pt1, pt2,pt3,pt4,pt5,pt6;
 Mat last_image;
 Mat new_min_image2;
 resize(old_image, new_min_image, Size(), 0.5, 0.5, INTER_CUBIC);
 resize(old_image, new_min_image2, Size(), 0.5, 0.5, INTER_CUBIC);
 //閉運算濾波
 morphologyEx(new_min_image, new_min_image, MORPH_CLOSE, element);
 blur(new_min_image,new_min_image,Size(10,10));
 Canny(new_min_image, new_min_image,8.9,9,3 );
 HoughLines(new_min_image,lines,1,CV_PI/180,158,0,0);
 //利用這個循環,可以繪制霍夫變換獲取直線的效果圖,但是為了簡潔性我暫時刪去了創建窗口繪制的代碼
 for (rsize_t i = 0 ; i < lines.size(); i++)
 {
 if (i!=lines.size()-2)
 {
 float zhongxinjuli = lines[i][0], theta = lines[i][1];
 double cos_theta = cos(theta), sin_theta = sin(theta);
 double x0 = zhongxinjuli * cos_theta, y0 = zhongxinjuli * sin_theta;
 pt1.x = cvRound(x0 - 1000 * sin_theta);
 pt1.y = cvRound(y0 + 1000 * cos_theta);
 pt2.x = cvRound(x0 + 1000 * sin_theta);
 pt2.y = cvRound(y0 - 1000 * cos_theta);
 line(new_min_image, pt1, pt2, Scalar(255, 255, 255), 1, LINE_AA);
 }
 }
 //獲取霍夫變換直線的交點
 for (rsize_t flag = 0,flag2=0; flag < lines.size(); flag++)
 {
 if (flag != lines.size() - 2)
 {
 float zx_juli = lines[flag][0], theta2 = lines[flag][1];
 double cos_theta2 = cos(theta2), sin_theta2 = sin(theta2);
 double x1 = zx_juli * cos_theta2, y1 = zx_juli * sin_theta2;
 lines_2pt[flag2][0]= cvRound(x1 - 1000 * sin_theta2);
 lines_2pt[flag2][1] = cvRound(y1 +1000 * cos_theta2);
 lines_2pt[flag2][2] = cvRound(x1 + 1000 * sin_theta2);
 lines_2pt[flag2][3] = cvRound(y1 - 1000 * cos_theta2);
 flag2++;
 }
 }
 for(int flag3=0;flag3<4;flag3++)
 {
 cout << "line_vector=" <<lines_2pt [flag3] << " ; " << endl;
 }
 pt3=getCrossPoint(lines_2pt[0],lines_2pt[1]);
 cout << "pt3=" << pt3 << " ; " << endl;
 pt4 = getCrossPoint(lines_2pt[1], lines_2pt[2]);
 cout << "pt4=" << pt4 << " ; " << endl;
 pt5 = getCrossPoint(lines_2pt[2], lines_2pt[3]);
 cout << "pt5=" << pt5<< " ; " << endl;
 pt6= getCrossPoint(lines_2pt[3], lines_2pt[0]);
 cout << "pt6=" << pt6 << " ; " << endl;
 //進行透視變換
 Point2f point_set[4] = { pt3,pt6,pt4,pt5 };
 Point2f point_set_transform[4] = { Point2f(50,50),Point2f(500,50) ,Point2f(50,600),Point2f(500,600) };
 last_kernel = getPerspectiveTransform(point_set,point_set_transform);
 warpPerspective(new_min_image2, last_image, last_kernel, Size(old_image.cols, old_image.rows));
 namedWindow("new_min_image");
 //繪制最終效果圖
 imshow("new_min_image", last_image);
 imwrite("task2_2矯正.png", last_image, compression_params);
 waitKey(0);
}
/*-------------------------------------------------------------------------------------------------------------------------------------
Copyright (C),2018---, HUST Liu
 File name:文檔矯正項目.cpp
 Author: 劉峻源 Version: 1 Date:2018.10.3
 Description:
   Part1
 根據作業(2)中的任務(1)(2)
 做了以下工作:
 (1)經過仿射變換,圖片縮小平移旋轉
 (2)調用函數進行仿射、透視變換
 (3)實現函數來做透視變換、仿射變換
------------    ----------    -----------   --------------------   ---- 
 Part2
 根據作業(2)中的任務(3)(4)
 做了以下工作:
 (1)利用讀入灰度圖像,并且經過濾波、邊緣提取、霍夫變換提取邊緣直線、得到
  紙張位置(即4個頂點)
 (2)利用透視變換矯正文檔
---------  *  ----------  *  --------------- * --------------- * ---------
 具體的任務過程:
 Part1
 調用OpenCV內的函數,編寫main_transform函數實現縮小、平移、旋轉和仿射變換功能
 (實際上后來openCV的仿射、透視我注釋掉了,不用它的函數了)
 實現仿射、透視變換函數 toushibianhuan、toushibianhuan_gai_fangshebianhuan,并在main_transform
 中調用
 注意:在main中調用標頭.h文件中的main_transfom函數實現縮小、平移、旋轉和仿射、透視變換!!!
------------    ----------   ------------------    -----------------  ---------
 任務過程:
 Part2
 在input_solve中,利用imread讀入灰度圖,調用blur、morphologyEx濾波,利用canny提取
 邊緣,調用HoughLines獲取邊緣直線,調用getCrossPoint獲取直線交點,調用
 getPerspectiveTransform獲取變換矩陣,調用warpPerspective實現透視變換
 注意:編寫input_solve函數來實現處理功能,本cpp是在main中調用標頭.h 中的input_solve函數!!!
------------------------------------------------------------------------------------------
 Others:  圖像輸入路徑:作業2_2/作業2_2/task2.png
 輸出圖像保存路徑:工程文件夾:作業2_2/作業2_2
 注意:在其他環境運行時一定要弄好更改讀入路徑!!!!
 May Function List: main、main_transform、input_solve
-----------------------------------------------------------------------------------------------
 History:
 as folwing
 ----- -------------   ----------------   ------------------  --------------  -----
 1.2018.10.3 
 2.by 劉峻源
 3.description:在工程作業2_1中將 comMatC、toushibianhuan、toushibianhuan_gai_fangshebianhuan移入頭文件
 image_solve.h中
 ----- -------------   ----------------   ------------------  --------------  -----
 1.2018.10.4
 2.by 劉峻源
 3.description:在工程作業2_2中將 main_transfom寫入main,去掉main_transform函數的waitKey(0)

 ----- -------------   ----------------   ------------------  --------------  -----
 --------------------------------------------------------------------------------*/


 /*-----------------------------------------------------------------
  標準openCV開頭     --
---------------------------------------------------------------------
引用頭文件和命名空間        --
------------------------------------------------------------------*/

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "標頭.h"
using namespace std;
using namespace cv;
int main()
{
 main_transform(90, 0, 100, "task2.png", 0.5, 0.5);
 input_solve("task2.png");
 waitKey(0);
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乡宁县| 阜新| 蒙阴县| 宣城市| 乌鲁木齐县| 长治市| 宁城县| 曲周县| 兴和县| 宜川县| 郁南县| 启东市| 温泉县| 桂东县| 星子县| 临洮县| 息烽县| 抚顺市| 治县。| 阿巴嘎旗| 柳江县| 松江区| 聂荣县| 穆棱市| 荥经县| 专栏| 正蓝旗| 固阳县| 巢湖市| 朝阳市| 邳州市| 克山县| 永和县| 山阴县| 汾西县| 乌兰察布市| 济阳县| 太原市| 开远市| 荣成市| 本溪|