#include <iostream>
#include <fstream>
#include <sstream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <string>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
Mat img = imread("C:\\Users\\Administrator\\Desktop\\圖片 001.jpg");
Mat img_gray;
cvtColor(img,img_gray,CV_RGB2GRAY);
namedWindow("gray");
imshow("gray",img_gray);
int rows = img.rows;
int cols = img.cols;
Point2f src[4]; //源圖像中的四個點
Point2f dst[4]; //目標圖像中的四個點
src[0].x = 1;
src[0].y = 121;
src[1].x = 639;
src[1].y = 130;
src[2].x = 1;
src[2].y = 417;
src[3].x = 639;
src[3].y = 417;
dst[0].x = 1;
dst[0].y = 1;
dst[1].x = 639;
dst[1].y = 1;
dst[2].x = 1;
dst[2].y = 288;
dst[3].x = 639;
dst[3].y = 288;
Mat t; //變換矩陣
t = getPerspectiveTransform(src,dst);
printf("transform matrix\n");
for(int i =0;i<3;i++) //打印透視變換矩陣
{
printf("% .6f ",t.at<double>(0,i));
printf("% .6f ",t.at<double>(1,i));
printf("% .6f \n",t.at<double>(2,i));
}
Mat pers_res(288,640,CV_8UC1); //保存透視變換後的矩陣
for (int i=121;i<=417;i++) //原圖像目標圖變換
{
for (int j=1;j<640;j++)
{
Mat sample = (Mat_<double>(3,1)<<j,i,1);
Mat r = t*sample;
double s = r.at<double>(2,0);
int x = cvRound(r.at<double>(0,0)/s); %除以s 歸一化爲齊次座標
int y = cvRound(r.at<double>(1,0)/s);
if ( (x>=0&&x<640)&&(y>=0&&y<288))
{
pers_res.at<uchar>(y,x) = img_gray.at<uchar>(i,j);
}
}
}
namedWindow("result");
imshow("result",pers_res);
}
目的是將原圖中一個梯形轉爲標準的矩形,所以用透視變換來做,原圖和變換後的圖如下。不過因爲透視變換,變換後的圖可能出現白道道,這是因爲變換過程中有拉扯現象,最好做一個插值處理。
變換後的標準矩形圖(我只取了原圖的下邊三條黑線最上邊黑線的上邊部分進行變換):