一、话说透视变换
OpenCV中透视变换的又分为两种:
- 稀疏透视变换
- 密集透视变换
我们经常提到的对图像的透视变换都是指密集透视变换,而稀疏透视变换在OpenCV的特征点匹配之后的特征对象区域标识中经常用到。一般情况下密集透视变换warpPerspective函数常与函数getPerspectiveTransform一起使用实现对图像的透视校正。而稀疏透视变换perspectiveTransform经常与findhomography一起使用。
二、原理公式
u,v是原始图片左边,对应得到变换后的图片坐标x,y,其中。
变换矩阵可以分作四部分来理解,表示线性变换,表示平移,产生透视,
所以可以理解成仿射等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。
重写之前的变换公式可以得到:
所以,已知变换对应的几个点就可以求取变换公式。反之,特定的变换公式也能新的变换后的图片。简单的看一个正方形到四边形的变换:
根据变换公式得到:
定义几个辅助变量:
都为0时变换平面与原来是平行的,可以得到:
不为0时,得到
求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。
三、实验
透视变换的一般过程:读入图片,获取边界点,定义目标边界点,获取转换矩阵,执行转换。
int main()
{
Mat src = imread("D:\\cv_study\\Exercise\\Perspective Transformation\\1.jpg");
vector<Point2f>src_coners(4);
src_coners[0] = Point2f(13, 134);
src_coners[1] = Point2f(271, 24);
src_coners[2] = Point2f(180, 411);
src_coners[3] = Point2f(398, 362);
circle(src, src_coners[0], 3, Scalar(0, 0, 255), 3, 8);
circle(src, src_coners[1], 3, Scalar(0, 0, 255), 3, 8);
circle(src, src_coners[2], 3, Scalar(0, 0, 255), 3, 8);
circle(src, src_coners[3], 3, Scalar(0, 0, 255), 3, 8);
vector<Point2f>dst_coners(4);
dst_coners[0] = Point2f(0, 300);
dst_coners[1] = Point2f(0, 0);
dst_coners[2] = Point2f(400, 300);
dst_coners[3] = Point2f(400, 0);
Mat warpMatrix = getPerspectiveTransform(src_coners, dst_coners);
Mat dst;
warpPerspective(src, dst, warpMatrix, dst.size(), INTER_LINEAR, BORDER_CONSTANT);
waitKey();
return 0;
}
有以上的结果看出,透视变换的结果比较理想。今天关于透视变换的内容就讲这么多,不足之处多多请多多见谅。