На моем двоичном изображении прямоугольные angular повернутые объекты известного размера. Я бы хотел получить наклон объекта с помощью выровненного по оси ограничительного прямоугольника, который возвращает regionprops MATLAB. Каковы мои предложения:
Пусть ширина ограничительной рамки будет W, сторона прямоугольника будет C, а угол наклона альфа
Тогда
Использование подстановки Вейерштрасса
После некоторого упрощения:
Решение уравнения для tan (alpha / 2) с
Для любого ненулевого наклона дискриминант положительный.
Logi c, кажется, в порядке, так же, как математика. Не могли бы вы указать, где я ошибаюсь, или как лучше получить наклон?
Вот соответствующий код MATLAB:
img = false(25,25);
img(5:16,5:16) = true;
rot_img = imrotate(img, 30, 'crop');
props = regionprops(bwlabel(rot_img),'BoundingBox');
bbox = cat(1,props.BoundingBox);
w = bbox(3);
h = 12;
a = -1*(1+w/h); b = 2; c = 1 - w/h;
D = b^2 - 4*a*c;
alpha = 2*atand((-b + sqrt(D))/(2*a));
%alpha = 25.5288
РЕДАКТИРОВАТЬ Спасибо за подсказки тригонометрии. Они значительно упрощают расчеты, но дают неправильный ответ. Как я теперь понимаю, вопрос задается неправильно. Что мне действительно нужно, так это найти наклон коротких линий (10-50 пикселей) с высокой точностью (+/- 0,5 градуса), положение линий не представляет интереса.
Подход, использованный в вопросе и ответы показывают лучшую точность для длинных строк, для c = 100 ошибка составляет менее 0,1 градуса. Это означает, что мы находимся в ошибке растеризации и нуждаемся в субпиксельной точности На данный момент у меня есть только один алгоритм, который решает проблему - преобразование Радона, но я надеюсь, что вы можете порекомендовать что-то еще.
p = bwperim(rot_img);
theta=0:0.1:179.9;
[R,xp] = radon(p,theta); %Radon transform of contours
a=imregionalmax(R,true(3,3)); %Regional maxima of the transform
[r,c]=find(a); idx=sub2ind(size(a),r,c); maxvals=R(idx);
[val,midx]=sort(maxvals,'descend'); %Choose 4 highest maxima
mean(rem(theta(c(midx(1:4))),90)) %And average corresponding angles
%29.85