Реализация эллипса структурного элемента

Я хочу реализовать следующее с помощью OpenCV (Я опубликую свою попытку в нижней части поста). Я знаю, что в OpenCV есть функция для чего-то подобного, но я хочу попробовать написать свою собственную.

В изображении (Mat) (система координат находится вверху слева, так как это изображение) ширины width и высота heightЯ хочу отобразить заполненный эллипс со следующими свойствами:

  • это должно быть сосредоточено на (width/2, height/2)

  • изображение должно быть двоичным, поэтому точки, соответствующие эллипсу, должны иметь значение 1, а остальные — 0

  • эллипс должен вращаться angle радианы вокруг источника (или градусы, это не имеет большого значения, я могу преобразовать)

  • эллипс: параметр большой полуоси a и параметр полуосновной оси b и эти два параметра также представляют размер этих осей на рисунке, так что «независимо от» width а также heightэллипс должен иметь большую ось размера 2*a и малая ось размера 2*b

Итак, я нашел уравнение, подобное этому (https://math.stackexchange.com/a/434482/403961) для моей цели. Мой код выглядит следующим образом … кажется, что он довольно хорошо работает на стороне вращения, но, к сожалению, в зависимости от угла поворота, РАЗМЕР (большая ось, не уверен насчет второстепенного) заметно увеличивается / уменьшается, что не нормально , поскольку я хочу, чтобы он имел одинаковый размер, независимо от угла поворота.

НОТА Самый большой размер, по-видимому, достигается, когда угол составляет 45 или -45 градусов, а наименьший — для углов, таких как -90, 0, 90.

Код:

inline double sqr(double x)
{
return x * x;
}

Mat ellipticalElement(double a, double b, double angle, int width, int height)
{
// just to make sure I don't use some bad values for my parameters
assert(2 * a < width);
assert(2 * b < height);

Mat element = Mat::zeros(height, width, CV_8UC1);

Point center(width / 2, height / 2);
for(int x = 0 ; x < width ; x++)
for(int y = 0 ; y < height ; y++)
{
if (sqr((x - center.x) * cos(angle) - (y - center.y) * sin(angle)) / sqr(a) + sqr((x - center.x) * sin(angle) - (y - center.y) * cos(angle)) / sqr(b) <= 1)
element.at<uchar>(y, x) = 1;
}

return element;
}

0

Решение

В твоем неравенстве проникла неприятная опечатка. Первое слагаемое должно быть

sqr((x - center.x) * cos(angle) + (y - center.y) * sin(angle)) / sqr(a)

Обратите внимание плюс знак вместо минус.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector