由于canny函数自带滤波算法,所以不再使用高斯算法,根据图像的直方图,canny函数选择两个阈值分别为100和180。而且图像宽500,高375,选用3*3的算子。
检测直线使用的函数是霍夫直线变换,得到的是每条直线的两个点的坐标
HoughLinesP(img_gray,plines,1,CV_PI/180.0,150,150,100);
选择搜索步长为一个像素,搜索角度步长是1°,可以使搜索得到的直线更加准确。为避免字母上直线的干扰,选择累加器的阈值为150,直线最短长度阈值为150,线段上最近两点之间的阈值为100。本步共得到六条直线,之后选择合适的直线求出交点。
定义一个函数Point2f Getintersection(Vec4i a, Vec4i b),输入一条直线的两个点,输出为交点的坐标。
求透视变换矩阵使用函数如下,输入变换前后的四个点的坐标得到透视变换矩阵warpMartrix = getPerspectiveTransform(srcCorners, dstCorners);
通过函数warpPerspective(img,result,warpMartrix,result.size(), INTER_LINEAR);可以得到变换后的新图像result
#include
using namespace cv;
using namespace std;
//求交点函数
Point2f Getintersection(Vec4i a, Vec4i b)
{
int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3];
int x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
float k1, k2, b1, b2;
Point2f pt;
k1 = float(y1 - y2) / (x1 - x2); b1 = y2 - k1 * x2;
k2 = float(y3 - y4) / (x3 - x4); b2 = y4 - k2 * x4;
if (k1 == k2)
return Point2f(-1, -1);
if ( x3 == x4){
k1 = float(y1 - y2) / (x1 - x2); b1 = y2 - k1 * x2;
pt.x = x3;
pt.y = k1 * pt.x + b1;
return pt;
}
if (x1 == x2 ){
pt.x = x1;
pt.y = k2 * pt.x + b2;
return pt;
}
pt.x = (b2 - b1) / (k1 - k2);
pt.y = k1 * pt.x + b1;
return pt;
}
int main()
{
Mat img, img_gray;
img = imread("1.jpg");
cvtColor(img, img_gray, CV_BGR2GRAY);
imshow("test", img);
waitKey(0);
Canny(img_gray, img_gray, 100, 180,3);
imshow("2", img_gray);
waitKey(0);
//霍夫直线检测
vector<Vec4i> plines;
HoughLinesP(img_gray,plines,1,CV_PI/180.0,150,150,100);
for (size_t i = 0; i < plines.size(); i++)
{
Vec4f hline = plines[i];
line(img, Point(hline[0], hline[1]), Point(hline[2], hline[3]), Scalar(0,0,255), 2, 8);
}//四条边分别为上3,下6,左4,右1
imshow("3", img);
waitKey(0);
//求交点
Point2f A,B,C,D;
A = Getintersection(plines[3], plines[4]);
B = Getintersection(plines[3], plines[1]);
C = Getintersection(plines[6], plines[4]);
D = Getintersection(plines[6], plines[1]);
circle(img, A, 5, Scalar(0, 0, 255),5);
circle(img, B, 5, Scalar(0, 0, 255),5);
circle(img, C, 5, Scalar(0, 0, 255),5);
circle(img, D, 5, Scalar(0, 0, 255),5);
imshow("4", img);
waitKey(0);
//透视变换
vector<Point2f> srcCorners(4);
srcCorners[0] = A;
srcCorners[1] = B;
srcCorners[2] = C;
srcCorners[3] = D;
vector<Point2f> dstCorners(4);
dstCorners[0] = Point(0, 0);
dstCorners[1] = Point(img.cols, 0);
dstCorners[2] = Point(0, img.rows);
dstCorners[3] = Point(img.cols, img.rows);
Mat warpMartrix = getPerspectiveTransform(srcCorners, dstCorners);
Mat result = Mat::zeros(img.size(), -1);
warpPerspective(img, result, warpMartrix, result.size(), INTER_LINEAR);
imshow("output", result);
waitKey(0);
return 0;
}