2012-10-19 5 views
1

Я пытаюсь обнаружить эллипс в изображении, используя opencv. Я нахожу контуры, которые включают эллипс, а также некоторые другие.Как проверить, является ли контур эллипсом?

Любые предложения, как я могу проверить, какие контуры являются эллипсом?

+0

Можете ли вы уточнить, что вы подразумеваете под «приблизительно»? – mathematician1975

+0

@ mathematician1975, я загрузил изображение, ну, я думаю, что поместить примерно немного, я изменю его! Спасибо – Shan

+0

Возможный дубликат [Обнаружение эллипса с помощью OpenCV] (http://stackoverflow.com/questions/10982988/ellipse-detection-with-opencv) – ArtemStorozhuk

ответ

3

Если я правильно вас понял, вы обнаружили контуры, некоторые из них являются эллипсами, а некоторые нет, и вы хотите решить, какие из них. Это правильно? Если да, я бы предложил использовать cv::fitEllipse(). Док говорит, что он соответствует эллипсу вектору точек, так что R-квадрат минимален. К сожалению, функция не возвращает явно значение R-квадрата. Вы можете возможно осуществить это самостоятельно ...

В качестве обходного пути, вы можете также использовать что-то типа:

  1. Получить контур С
  2. Установите эллипс Е к С
  3. Сравнить E до C.

Для сравнения их вы можете использовать моменты (см. cv::moments() и cv::matchShapes()). Я не думаю, что вам нужны инвариантные моменты здесь.

В качестве альтернативы вы можете нарисовать C и E, чтобы найти, какая часть перекрытия поверхности.

Успехов,

0

@Ahsan - вы должны перебрать все контуры и попытаться соответствовать эллипсу. Если вы нашли подходящую кривую математику трудной короткий маршрут будет

как - перебирать каждый контур - отбрасывать не являющиеся выпуклые контуры - Теперь сделайте маску из текущего контура и не shapeMatching с помощью функции резюме :: matchShapes ,

0

fitEllipse дать нам RotatedRect.

И мы можем использовать свойство эллипса, которое может быть преобразовано в круг.

double is_ellipse(std::vector<cv::Point> const& cloud, RotatedRect const& rr) 
{ 
    double distance =0; 

    for(auto const& point: cloud) 
    { 
     Point2f unit; 
     unit.x = ((rr.center.x - point.x ) * cos(- rr.angle*(3.1415926/180)) - (rr.center.y - point.y ) * sin(- rr.angle*(3.1415926/180))) * 2/rr.size.width ; 
     unit.y = ((rr.center.x - point.x ) * sin(- rr.angle*(3.1415926/180)) + (rr.center.y - point.y ) * cos(- rr.angle*(3.1415926/180))) * 2/rr.size.height; 

     double len = sqrt(unit.x* unit.x + unit.y * unit.y); 
     distance += fabs(1- len); 
    } 
    return distance/cloud.size(); 
} 

Здесь используется для расчета среднего расстояния от границы круга. Легко изменить некоторые другие статистические функции, такие как: max, отклонение.