在Matlab中确定三角形的方向

时间:2015-01-30 17:21:04

标签: matlab image-processing computer-vision matlab-cvst

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

目标是提议的

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

如果有任何不清楚的地方,请提出任何问题。非常感谢你

更新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)

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

2 个答案:

答案 0 :(得分:0)

我有一个非常直率的解决方案。它可能会奏效。我没有真正尝试过,因为没有图像可供使用。因此,如果失败,请发布错误。

假设: - 您已经过滤了图像并获得了仅包含三角形“OR”并且噪声均匀的二进制图像。

  1. 现在您可以拍摄0度图像(image1)。过滤它并获得二进制图像(bw1)。

  2. 因此,当您尝试降落四旋翼飞行器时,请拍摄图像(图像2),将其转换为二进制(bw2)。

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

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

  5. 现在再次找到这两个图像之间的相关性。

  6. 针对所有角度执行此操作。

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

  8. 术语最大值表示,您可能找不到相关性为1,因为这很大程度上取决于您的过滤技术以获得完美的二进制图像。

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

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

    祝你好运。不错的项目。

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

答案 1 :(得分:0)

我认为最简单快捷的方法是找到目标并将图像二值化。之后使用regionprops()并阅读&#34; Orientation&#34;财产阅读方向。

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

编辑:

我只是想在这里有一些很好的矢量化函数;)所以如果速度是最高优先级,你可以轻松地将你自己的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

形象时刻很有可能,玩得开心!