OpenCV4学习笔记(75) 您所在的位置:网站首页 ar效果是什么意思啊 OpenCV4学习笔记(75)

OpenCV4学习笔记(75)

2024-06-28 09:44| 来源: 网络整理| 查看: 265

今天要整理记录的是利用OpenCV中ArUco模块的aruco标记实现一个增强现实的小应用,当然了本次笔记的内容也是需要建立在之前的《OpenCV4学习笔记(72)》基础上的。

所谓增强现实(Augmented Reality),其实是一种将虚拟信息与真实世界巧妙融合的技术,通过技术手段将计算机生成的文字、图像、三维模型、音乐、视频等虚拟信息模拟仿真后,应用到真实世界中,两种信息互为补充,从而实现对真实世界的“增强”。在这里,我们主要利用aruco标记实现将图像、视频这些虚拟信息应用到拍摄下来的真实世界中。

首先,我们需要创建并打印出四个aruco标记,这四个标记作为我们确定现实增强区域的基准,例如下面这几张图像:在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 可以看到这四个aruco标记包围形成了一个大的四边形区域,这个区域就是我们要进行操作的ROI区域了,当然了还可以把这四个aruco标记裁剪下来,然后贴在门上、窗上、相框中等等场景,这样更有利于增强现实的体现。这里我们就不做裁剪了,就在这张纸上进行实验。下面将这张包含aruco标记的纸图像表述为场景图像。

首先,我们需要对场景图像进行aruco标记的检测,那么就需要先加载拍摄时所用相机的内参矩阵和畸变系数,这里默认已经对相机标定好了,以后有机会再整理一下相机标定的内容。

//加载图像 Mat inputImage = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\FourMarkerVideo.jpg"); resize(inputImage, inputImage, Size(600, 800)); Mat test_image = inputImage.clone(); //加载相机内参和畸变系数 cv::Mat cameraMatrix, distCoeffs; vector camera = { 657.1548323619423, 0, 291.8582472145741,0, 647.384819351103, 391.254810476919,0, 0, 1 }; cameraMatrix = Mat(camera); cameraMatrix = cameraMatrix.reshape(1, 3); vector dist = { 0.1961793476399528, -1.38146317350581, -0.002301820186177369, -0.001054637905895881, 2.458286937422959 }; distCoeffs = Mat(dist); distCoeffs = distCoeffs.reshape(1, 1);

然后对场景图像中的aruco标记进行检测

//进行标记检测 auto dictionary = aruco::getPredefinedDictionary(DICT_6X6_250); vectorcorners, rejectedImaPoints; vectorids; auto parameters = aruco::DetectorParameters::create(); aruco::detectMarkers(test_image, dictionary, corners, ids, parameters, rejectedImaPoints, cameraMatrix, distCoeffs); //aruco::drawDetectedMarkers(test_image, corners, ids, Scalar(0, 255, 0));

接着我们要寻找所需的ROI区域,也就是四个aruco标记包围而成的一个四边形区域,那么我们需要确定这个四边形的四个顶点。我暂时考虑了两个方法,一是对四个标记的所有角点中的x、y坐标进行排序,找到正数和倒数的前两个值,再进行配对,从而找到四个顶点,这个方法在对于场景图像发生变化时、例如是场景视频的情况下有比较好的效果。二是直接从检测到的四个标记的ID值来索引标记,并获取四边形ROI区域中的对于角点,这个方法相对来说更简单粗暴,但是适用性会比较差,尤其是场景图像发生旋转的情况下比较难达到好的效果。

这里我使用的场景图像是一张固定的图像,也就是上面拍摄的场景图像,所以这里我使用第二个方法

//提取四个标记形成的ROI区域 vector roi_box_pt(4); //寻找方框的四个顶点,从检测到标记的顺序决定 roi_box_pt[0] = corners[3][0]; roi_box_pt[1] = corners[2][1]; roi_box_pt[2] = corners[0][2]; roi_box_pt[3] = corners[1][3];

接着我们需要读取要替换ROI区域的目标图像,并提取四个顶点

//读取替换图像 Mat new_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\pig.jpg"); int width = new_image.cols; int height = new_image.rows; //提取替换图像的四个顶点 vector new_image_box(4); new_image_box[0] = Point(0, 0); new_image_box[1] = Point(width, 0); new_image_box[2] = Point(width, height); new_image_box[3] = Point(0, height);

然后将目标图像从原视平面到场景图像的视平面做透视变换

//计算从替换图像到目标ROI图像的3x3单应性矩阵 Mat H = findHomography(new_image_box, roi_box_pt); Mat roi_new_image; //进行透视变换 warpPerspective(new_image, roi_new_image, H, test_image.size(), INTER_CUBIC);

然后为了将场景图像中的ROI区域挖空,我们需要设置一个掩膜,然后和场景图像进行按位与操作,最后将场景图像和目标图像通过加权相加融合,实现对场景图像的增强操作

//制作掩膜 Mat mask = Mat(test_image.size(), CV_8UC3,Scalar(255,255,255)); for (int i = 0; i if (roi_new_image.at(i, j) != Vec3b(0,0,0)) { mask.at(i, j) = Vec3b(0, 0, 0); } } } Mat kernel = getStructuringElement(MorphShapes::MORPH_RECT, Size(3, 3)); dilate(mask, mask, kernel); //用透视变换后的替换图像,替换原图像中的ROI区域 Mat result; bitwise_and(test_image, mask, test_image); addWeighted(test_image, 1, roi_new_image, 0.7, 1.0, result); namedWindow("result", WINDOW_FREERATIO); imshow("result", result);

得到的效果如下: 在这里插入图片描述 由于这里的aruco标记是打印在一张纸上,所以看起来效果没有特别的好,但是试想下如果将它们裁剪下来,并且贴在相框上或者是窗上,再对拍摄下的图像进行增强现实操作,那是不是感觉就不一样了(╹ڡ╹ )

而且,假如我们使用的场景图像是实时视频流中的每一帧图像,那么还可以实现实时拍摄的增强现实效果,这样的话能得到更好的AR体验,当然了这样的话对电脑的要求就会比较高了。。。我也尝试过一下在实时视频流中进行处理,但是卡帧劝退了我。。。

今天尝试着将虚拟图像信息应用到了真实的场景图像中,实现一个比较有趣的AR效果,下次笔记再来尝试一下将视频信息应用到真实场景当中去,那本次笔记到此结束啦。

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有