在 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" 且噪声均匀的二值图像。
现在您可以拍摄 0 度图像 (image1)。过滤得到二值图像(bw1).
因此,当您尝试让四旋翼着陆时,拍摄图像 (image2),将其转换为二进制 (bw2)。
现在找出这两幅图像之间的相关性{corr2(bw1, bw2)}。将其存储在变量中。
以步长角旋转图像。让角度为5度。 {imrotate(bw2, 5)}
现在再次找出这两张图片之间的相关性。
对所有角度都这样做。
方位是角度(旋转次数* 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.
影像时刻很给力,玩得开心!
我正在做一个项目,通过视觉识别自动执行四旋翼飞行器在目标上的着陆。我有通过 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" 且噪声均匀的二值图像。
现在您可以拍摄 0 度图像 (image1)。过滤得到二值图像(bw1).
因此,当您尝试让四旋翼着陆时,拍摄图像 (image2),将其转换为二进制 (bw2)。
现在找出这两幅图像之间的相关性{corr2(bw1, bw2)}。将其存储在变量中。
以步长角旋转图像。让角度为5度。 {imrotate(bw2, 5)}
现在再次找出这两张图片之间的相关性。
对所有角度都这样做。
方位是角度(旋转次数* 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.
影像时刻很给力,玩得开心!