【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
说到透视变换,以前我也不明白为什么有这样一个需求。后来在tier1做车道线检测的时候,才知道如果把camera拍摄到的图像做一次透视转换之后,再用传统的方法进行车道线检测,这样正确率要高得多。也就是基于这个原因,才让我第一次知道了opencv下面原来有一个透视变换的功能。如果大家还没有一个直观的印象,可以看下面这个范例。没有透视转换之前,图象是这样的,
做了透视转换之后,图像变成了这样,
可以想一想,如果我们需要做ocr字符检测,是不是变换后的图像更容易做字符检测和字符识别。或者简单一点理解,可以把透视变换看成是带俯仰角的旋转变换。
1、创建工程和创建流程
在qmacvisual当中,第一步还是创建工程和创建流程,这是少不了的。
2、输入图片
输入图片直接采用【图像处理】里面的【获取图像】,这一步之前也练习了很多次,暂且不谈。
3、导入透视变换的控件
透视变换的控件,它的位置位于【图像处理】下面。我们直接从树形节点,把对应的控件拖到流程窗口中即可。双击对应的窗口,不出意外,可以看到这样的内容,
整个图像中,有两处需要配置。一处是输入图像,这部分比较简单。另外一处是输入点和输出点。所谓的输入点,就是源图像中关键区域的位置信息,而输出点呢,则是希望转换后区域所在的位置。对于输入点,一般是通过鼠标移动的方式,来进行位置信息获取的,获取之后用全局变量记录下来。而输出点,一般就是自己简单规划下即可。这样有了输入点和输出点,就可以构建一个旋转矩阵,有了这个矩阵就可以把原来的图像转换成新的图像。这就是透视变换的基本原理。
图中的var0~var7,都是全局变量中定义的,
4、测试流程
整个测试流程可以稍微拓展下,添加图像导入和透视变换之外,再添加一个图像显示,这样效果更好一点。
5、实现方法
通过阅读透视变换的原理,我们发现整个实现的流程并不复杂。最关键的部分还是如何计算透视转换矩阵。这部分可以在代码上面看的比较明显一点,
int frmPerspectiveTransform::RunToolPro()
{
try
{
//其他代码
//创建用于输入透视的四个点坐标
std::vector<cv::Point2f> src =
{
input_point1,
input_point2,
input_point3,
input_point4
};
//创建用于输出透视的四个点坐标
std::vector<cv::Point2f> dst =
{
output_point1,
output_point2,
output_point3,
output_point4
};
//获取透视矩阵
cv::Mat data = cv::getPerspectiveTransform(src, dst);
//进行透视操作
cv::warpPerspective(srcImage, dstImage, data, srcImage.size());
GetToolBase()->m_Tools[tool_index].PublicImage.OutputImage = dstImage;
GetToolBase()->m_Tools[tool_index].PublicResult.State = true;
return 0;
}
catch (...)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
}