Определить ориентацию треугольника в Matlab

Я работаю над проектом по автоматической посадке квадротора путем визуального распознавания цели. У меня есть код для определения цели с помощью функций HOG. Теперь идея состоит в том, чтобы найти треугольник, который является равнобедренным, и измерить линии, чтобы я мог определить ориентацию таким образом. Я попробовал Hough, но не могу добиться успеха.

Цель является предложенной

цельи состоит из равнобедренного треугольника внутри круга. Но если вы можете придумать лучший вариант, пожалуйста, дайте мне знать.

Пожалуйста, задавайте любые вопросы, если что-то неясно. большое спасибо

Обновление 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 Classifer: 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 ответа

Решение

Я думаю, что самый простой и быстрый способ - найти цель и преобразовать изображение в двоичную форму. Потом использовать regionprops() и прочитайте свойство "Ориентация", чтобы прочитать ориентацию.

Если вы не можете использовать этот набор инструментов, эту функцию очень легко реализовать, рассчитав ковариационную матрицу вашего региона. Дайте мне знать, если вам нужны советы по этому вопросу.

Редактировать:

Я просто хотел, чтобы здесь были некоторые хорошо векторизованные функции;) поэтому, если скорость является главным приоритетом, вы можете легко написать свою собственную 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

для вашей ориентации и ковариационной матрицы. Подробнее об этом здесь.

Моменты изображения очень веселы, веселитесь!

Я имею в виду очень тупое решение. Это может сработать. Я на самом деле не пробовал, так как нет изображения для работы. Так что, если не получится, опубликуйте ошибку.

Допущения:- Вы отфильтровали изображение и получили двоичное изображение, которое содержит только треугольник "ИЛИ" с равномерным шумом.

  1. Теперь вы можете сделать снимок в 0 градусов (изображение1). Отфильтруйте его и получите двоичное изображение (bw1).

  2. Поэтому, когда вы пытаетесь высадить свой квадротор, возьмите изображение (image2), преобразуйте его в двоичный код (bw2).

  3. Теперь найдите корреляцию между этими двумя изображениями { corr2(bw1, bw2)}. Сохраните это в переменной.

  4. Поворот изображения с шагом шага. Пусть угол будет 5 градусов. { imrotate(bw2, 5)}

  5. Теперь снова найдите корреляцию между этими двумя изображениями.

  6. Сделайте это для всех углов.

  7. Ориентация будет угол (№ поворота * 5), где корреляция является максимальной.

Термин "максимум" означает, что вы можете не найти корреляцию равной 1, поскольку это сильно зависит от ваших методов фильтрации для получения идеального двоичного изображения.

Я также согласен с тем, что для вычисления корреляции для всех углов требуются высокая скорость вычислений, а также длительное время. Это было бы очень трудно достичь в режиме реального времени, если у вас нет высокой скорости вычислений. (В этом случае вы можете взглянуть на Parallel Computing Toolbox) специально parfor.

Надеюсь, это было полезно для вас. Оставьте комментарий, если вы столкнулись с какой-либо ошибкой.

Наконец-то удачи. Хороший проект.

PS Pad белые или черные пиксели в зависимости от вашего двоичного изображения при повороте изображения.

Другие вопросы по тегам