基于C++_Opencv霍夫直线+透视变换

结果基于C++_Opencv霍夫直线+透视变换_第1张图片

具体步骤:

一读入图片、灰度化、canny边缘检测

由于canny函数自带滤波算法,所以不再使用高斯算法,根据图像的直方图,canny函数选择两个阈值分别为100和180。而且图像宽500,高375,选用3*3的算子。
基于C++_Opencv霍夫直线+透视变换_第2张图片

二 直线检测

检测直线使用的函数是霍夫直线变换,得到的是每条直线的两个点的坐标
HoughLinesP(img_gray,plines,1,CV_PI/180.0,150,150,100);
选择搜索步长为一个像素,搜索角度步长是1°,可以使搜索得到的直线更加准确。为避免字母上直线的干扰,选择累加器的阈值为150,直线最短长度阈值为150,线段上最近两点之间的阈值为100。本步共得到六条直线,之后选择合适的直线求出交点。
基于C++_Opencv霍夫直线+透视变换_第3张图片

三 求四条直线的交点

定义一个函数Point2f Getintersection(Vec4i a, Vec4i b),输入一条直线的两个点,输出为交点的坐标。
基于C++_Opencv霍夫直线+透视变换_第4张图片

四求透视变换矩阵,进行透视变换

求透视变换矩阵使用函数如下,输入变换前后的四个点的坐标得到透视变换矩阵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;
}

你可能感兴趣的:(opencv,计算机视觉)