本周文件交换精选

我们最好的用户提交

最小边界矩形,以及更多!

布雷特本周的选择是一套最小边界对象,通过约翰D 'Errico.我也对朱利安diener,因为他二维最小边界盒函数。

在开发自动跟踪视频对象的代码过程中,我发现我需要创建一个“最小边界矩形”来包围检测到的点。有一个很好的演示在计算机视觉工具箱中,用于跟踪移动人脸的点由多边形创建的polyshape命令。一切都很好;它工作得很好,而且非常快。但出于其他原因,我更喜欢使用“images.roi”。对象创建的drawrectangle命令(它本身是一个方便的函数矩形().)

上述示例的修改版本如下所示:

vidObj = VideoReader (“tilted_face.avi”);videoFrame = readFrame (vidObj);togglefig (“面子”追踪) imgH = imshow(videoFrame);faceDetector = vision.CascadeObjectDetector ();bbox = faceDetector (videoFrame);bboxPoints = bbox2points(bbox(1,:)));thisPoly = polyshape (bboxPoints);持有polyH =情节(thisPoly,“FaceAlpha”0,“EdgeColor”“y”“线宽”2);点= detectMinEigenFeatures (rgb2gray (videoFrame),“投资回报”, bbox);pointTracker =愿景。PointTracker (“MaxBidirectionalError”2);点= points.Location;初始化(pointTracker点,videoFrame);oldPoints =点;抽搐;hasFrame (vidObj)%获取下一帧,更新可视化:videoFrame = readFrame (vidObj);imgH。CData = videoFrame;%追踪积分。注意,有些分数可能会丢失。[points, isFound] = pointTracker(videoFrame);visiblePoints = points(isFound,:);olddinliers = oldPoints(isFound,:);如果>= 1%需要至少2分[xform, oldInliers, visiblePoints] = estimateGeometricTransform(...oldInliers visiblePoints,“相似”“MaxDistance”4);bboxPoints = transformpointforward (xform, bboxPoints);thisPoly = polyshape (bboxPoints);polyH。形状= thisPoly;oldPoints = visiblePoints;选点(pointTracker oldPoints);结束imgH。CData = videoFrame;drawnow结束t = toc;%清理释放(pointTracker);%(在我的笔记本电脑上,处理while循环大约需要6.5秒。)

但是如何用旋转的矩形来替换多边形呢?幸运的是,我们有File Exchange,在这里搜索“最小边界矩形”很快就找到了John的最小边界圆、球体、平行四边形、四边形、半圆、三角形和矩形的函数“套件”。

正如我们所期望的那样,John的函数写得很好,也有很好的注释。用最小边界矩形替换多边形是一件简单的事情,这并不奇怪,它可以计算输入点的凸包。注意:John的函数返回x -y -目标矩形的坐标,其面积和周长相同:

[rectx recty,面积,周长]= minboundrect (x, y,度量)

(事实上,你可以使用“度量”参数选择,以面积或周长最小化,面积是默认值。)我需要旋转角度作为输入的三角形drawrectangle.它花了一些时间来修改minboundrect将作为附加输出返回edgeangles参数,它是内部计算的。片刻之间,我们有:

vidObj。CurrentTime = 0;%重置并重新使用VideoReader对象videoFrame = readFrame (vidObj);%togglefig('Face Tracker', true) %清除并重用图形% imgH = imshow (videoFrame);bbox = faceDetector (videoFrame);% hRect = drawrectangle('Position', bbox,…% 'FaceAlpha', 0, 'Color', 'y', 'LineWidth', 2);bboxPoints = bbox2points(bbox(1,:)));点= detectMinEigenFeatures (rgb2gray (videoFrame),“投资回报”, bbox);pointTracker =愿景。PointTracker (“MaxBidirectionalError”2);点= points.Location;初始化(pointTracker点,videoFrame);oldPoints =点;抽搐;hasFrame (vidObj)%获取下一帧,更新可视化:videoFrame = readFrame (vidObj);% imgH。CData = videoFrame;%追踪积分。注意,有些分数可能会丢失。[points, isFound] = pointTracker(videoFrame);visiblePoints = points(isFound,:);olddinliers = oldPoints(isFound,:);如果>= 1%需要至少2分[xform, oldInliers, visiblePoints] = estimateGeometricTransform(...oldInliers visiblePoints,“相似”“MaxDistance”4);bboxPoints = double(transformPointsForward(xform, bboxPoints));% |vertToPos|是我写的一个助手函数;它是逆变器% < //www.tianjin-qmedu.com/help/vision/ref/bbox2points.html | bbox2points | >。测试=“约翰。”开关测试情况下“约翰。”[rectx, recty, theta] =...minboundrect (bboxPoints (: 1) bboxPoints (:, 2));rectPos = vertToPos([rectx, recty]);情况下“于连”[rect, theta] = minBoundingBox(bboxPoints');rectPos = vertToPos(矩形);结束θ= 360 - rad2deg(θ(1));hRect。位置= rectPos;hRect。RotationAngle =θ;oldPoints = visiblePoints;选点(pointTracker oldPoints);结束% imgH。CData = videoFrame;drawnow结束t = toc;%清理释放(pointTracker);

循环播放所有视频帧需要8.3秒;minboundrect每帧增加4毫秒的开销。(不坏!)

顺便说一句,我也找到了julien的“2D最小边界框”贡献的方法(并进行了测试)。Julien(显然避免大写)写道,他的代码是“完全向量化的”,因此“更适合大的点集”。我没有在大型数据集上测试差异,但是对于我的用例,我没有检测到性能差异。非常好,先生们——谢谢你们两位!

一如既往,我欢迎你的到来想法和意见

发布与MATLAB®R2019b

|
  • 打印
  • 发送电子邮件

评论

要留下评论,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。