在 Matlab 中确定三角形的方向

Determine the orientation of a triangle in Matlab

我正在做一个项目,通过视觉识别自动执行四旋翼飞行器在目标上的着陆。我有通过 HOG 功能检测目标的代码。现在的想法是找到等腰三角形,然后测量这些线,这样我就可以确定方向。我试过霍夫,但我无法成功。

目标是提议的

,由一个圆内嵌一个等腰三角形组成。但如果你能想到更好的,请告诉我。

如有不明之处,欢迎提问。非常感谢

更新 1:

当我只将目标作为图像处理时,@McMa 的想法很有效。这是代码:

clc; close all;
im=imread('target.bmp');
im=rgb2gray(im);
im2=imcrop(im,[467.51 385.51 148.98 61.98]);
im2=imcomplement(im2);
im2=imrotate(im2,0);

s=regionprops(im2,'Area','Centroid','Extrema','Orientation');

[imH,imW]=size(im2);
if imH-s(end).Centroid(2) < imH/2
    state=1;        % Upright
else
    state=2;        % Upside down
end

imshow(im2);hold on
plot(s(end).Centroid(1), s(end).Centroid(2), 'b*')

if s(end).Orientation>0
    degrees=s(end).Orientation;
else
    degrees=s(end).Orientation+180;
end

if (0<degrees)&&(degrees<89.99) && state==2
    degrees=degrees+180;
elseif (90<degrees) && (degrees<179) && state==1
    degrees=degrees+180;
end

fprintf('The orientation is %g degrees\n',degrees)

更新 2:

现在我有另一个问题:我需要以某种方式知道相机是看到整个目标还是只看到小圆圈+三角形。在计算方向之前我需要这个。

我尝试了很多选择。比如我想统计圆圈的个数,有2个就是大目标,有1个就是小目标。但它们没有被很好地检测到。即使我玩灵敏度,它也不是一个可靠的方法。

图片:https://www.dropbox.com/s/7mbpna3xfquq5n7/P0016.bmp?dl=0 分类器:https://www.dropbox.com/s/236vm3romw56983/Cascade1Matlab.xml?dl=0

 im=imread('P0016.bmp');
detector = vision.CascadeObjectDetector('Cascade1Matlab.xml');
    bbox = step(detector, im);       % Detect the target.
detectedImg = insertObjectAnnotation(im, 'rectangle', bbox, 'target');         % Insert bounding boxes and return marked image.
imshow(detectedImg)

BW=rgb2gray(im);
BW=imcrop(BW,bbox(1,:) +[0 0 10 10]);
[imH,imW]=size(im);
centers = imfindcircles(im,[1 round(imH)]);
figure;hold on;
imshow(im);
plot(centers(:,1),centers(:,2),'r*','LineWidth',4)

我也尝试过其他方法,例如欧拉数,但没有成功,我找不到任何合适的方法。

我有一个非常直接的解决方案。它可能会起作用。我还没有真正尝试过,因为没有图像可以处理。因此,如果失败,post 错误。

假设:- 你已经对图像进行了过滤并获得了仅包含三角形 "OR" 且噪声均匀的二值图像。

  1. 现在您可以拍摄 0 度图像 (​​image1)。过滤得到二值图像(bw1).

  2. 因此,当您尝试让四旋翼着陆时,拍摄图像 (image2),将其转换为二进制 (bw2)。

  3. 现在找出这两幅图像之间的相关性{corr2(bw1, bw2)}。将其存储在变量中。

  4. 以步长角旋转图像。让角度为5度。 {imrotate(bw2, 5)}

  5. 现在再次找出这两张图片之间的相关性。

  6. 对所有角度都这样做。

  7. 方位是角度(旋转次数* 5),其中相关性为最大

术语最大值表示,您可能不会发现相关性为 1,因为这在很大程度上取决于您的过滤技术以获得完美的二值图像。

我也承认计算所有角度的相关性需要很高的计算速度和很长的时间。如果你没有很高的计算速度,这将很难实时实现。 (在这种情况下,您可以查看 Parallel Computing Toolbox)特别是 parfor.

希望这对您有用。 Post 如果您遇到任何错误,请发表评论。

终于祝你好运了。不错的项目。

P.S. 在旋转图像时根据您的二进制图像填充白色或黑色像素。

我认为最简单和最快的方法是找到目标并对图像进行二值化。之后使用regionprops()和阅读"Orientation"属性来阅读方向。

如果您不能使用该工具箱,则可以通过计算您所在地区的协方差矩阵轻松实现该功能。如果您需要一些提示,请告诉我。

编辑:

我恰好在这里有一些很好的矢量化函数 ;) 所以如果速度是重中之重,你可以轻松地编写自己的 regionprops() 修剪到最低限度,如下所示:

function M=ImMoment(Image,ii,jj)

    ImSize=size(Image);

    K=repmat((1:ImSize(1))',1,ImSize(2)).^ii; 
    J=repmat(1:ImSize(2),ImSize(1),1).^jj;
    M=K.*J.*Image;

    M=sum(M(:));

end

对于图像时刻和

function [Matrix,Centroid,Angle]=CovMat(Image)

    Centroid=[ImMoment(Image,0,1)/ImMoment(Image,0,0),...
         ImMoment(Image,1,0)/ImMoment(Image,0,0)];

     Miu20=ImMoment(Image,0,2)/ImMoment(Image,0,0)-Centroid(1)^2;
     Miu02=ImMoment(Image,2,0)/ImMoment(Image,0,0)-Centroid(2)^2;
     Miu11=ImMoment(Image,1,1)/ImMoment(Image,0,0)-Centroid(1)*Centroid(2);

     Matrix=[Miu20,Miu11   %Covariance Matrix in case you need it for anything...
             Miu11,Miu02];

     Angle=1/2*atand(2*Miu11/(Miu20-Miu02)); %Your orientation

end

用于您的方向和协方差矩阵。更多信息 here.

影像时刻很给力,玩得开心!