Перейти к содержимому
Compvision.ru
egens

Проблемы при работе с классом Mat

Recommended Posts

В переменной frame - IplImage - капча с камеры.

Преобразую тип и объявляю 2 переменные.

Mat framemat(frame), gray, bw;

Обесцвечиваю исходник.

cvtColor(framemat, gray, CV_BGR2GRAY);

Нахожу маску по уровню

threshold(gray,bw,10,255,THRESH_BINARY_INV);

Убираю шум

morphologyEx(bw, bw, MORPH_OPEN,

getStructuringElement(MORPH_ELLIPSE,Size(5,5),Point(-1,-1)),

Point(-1,-1),3,BORDER_CONSTANT,morphologyDefaultBorderValue());

И тут натыкаюсь на эксепшен:

fitEllipse(bw);

На самом деле нужно выполнить функцию minEnclosingCircle, но даже fitEllipse не хочет выполняться.

Никак не могу разобраться с этой проблемой.. В мануале написано, что аргумент fitEllipse - объект класса Mat и типа CV_32SC2 или CV_32FC2, может быть ошибка в этом, не могу понять как сменить тип..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

хм, видимо никто не использует C++ Api..

я правильно понимаю, что лучше пользоваться C API?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Для меня C API банально привычней. А что за эксепшен? Не смотрел в отладчике кто его кидает?

Могу вечерком глянуть, сейчас ничего под рукой нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Посмотрите стандартный пример: C:\OpenCV2.0\samples\c\minarea.c

там все есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Для меня C API банально привычней. А что за эксепшен? Не смотрел в отладчике кто его кидает?

Могу вечерком глянуть, сейчас ничего под рукой нет.

отладчик не хочет входить в функцию fitEllipse() - эксепшен вылетает на step into.

Посмотрите стандартный пример: C:\OpenCV2.0\samples\c\minarea.c

там все есть.

да вроде как там нет того что мне надо, там все на C API написано. используются функции 'cv...'

я правда смотрел везде где только можно..

реализовал на C API все что хотел.. с C++ API так и не смог разобраться в этом моменте. так что вопрос открытый..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если посмотреть на функцию:

cv::RotatedRect cv::fitEllipse( const Mat& points )

{

CV_Assert(points.isContinuous() &&

(points.depth() == CV_32S || points.depth() == CV_32F) &&

((points.rows == 1 && points.channels() == 2) ||

points.cols*points.channels() == 2));

CvMat _points = points;

return cvFitEllipse2(&_points);

}

то можно увидеть, что, во-первых, тип элементов матрицы должен быть CV_32S или CV_32F, и, во-вторых, её размерность должна быть: 1 строка, два канала, или 1 столбец, два канала, или, 2 столбца, один канал.

Ты же подаёшь ей на вход матрицу другого типа, не подходящую по размерам. Вот оно а падает на ассерте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Nuzhny

спасибо! да, после того, как я реализовал систему на C API, этот вопрос для меня более понятен. в доках очень мало инфы про библиотечные типы матриц и их преобразование.. возможно буду переделывать все обратно..

кстати, как узнать тип существующей переменной Mat? Можно ли его получить в виде 'CV_32S'?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В виде строки 'CV_32S' получить нельзя (только если ты сам захочешь сделать ассоциативный массив). Да и зачем? По идее, достаточно получить числовое значение через mat.depth(). В крайнем случае посмотреть в файле cxtypes.h соответствие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

еще есть такие вопросы

функция cv::findContours возвращает контуры как vector<vector<Points>> contours

контуры ищутся для каждого кадра видео. если переменная contours объявлена до цикла получения видео, после первой записи в нее, вторую сделать не удается. если ее задавать внутри цикла, после исполнения программы получаю stack around variable corrupted.

и известны ли вам штатные средства преобразования vector<vector<Points>> в Mat CV_C32SC2 - столбец

также не пойму почему функция

namedWindow("Trulala");

создает окошко с названием "MMMMTrulala"

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тут вот какое дело. Для использования С++ API необходимо, чтобы dll и exe были собраны одним компилятором с одинаковыми опциями.

Например, ошибка с заголовком окна. namedWindow принимает параметром std::string. В момент вызова namedWindow("Trulala"); в твоём exe создаётся объект класса std::string, который бинарно не совпадает с объектом std::string, который уже скомпилирован в dll. Тут даже в рамках одного компилятора debug и release варианты STL не идентичны.

Поэтому, повторюсь, использование С++ возможно только в одном случае: ты компилируешь OpenCV с определёнными опциями компилятора и с теми же опциями компилируешь свой exe. Теперь они совместимы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

то есть, в устанавливаемой изначально библиотеке существуют какие то конфликты? я думал она одновременно поддерживает оба API..

можно на пальцах, как избежать ошибок? или где почитать про это?

а про контуры в моем предыдущем сообщении можешь подсказать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Поддерживает-то оба, но с бинарной совместимостью объектов С++ всегда была проблема. Собственно, имеется её решение - COM-объекты в Windows. Я думаю, ты знаешь, что там слишком навороченно для того, чтобы их просто так использовать. Где об этом почитать... Многостраничные обсуждения на форумах и собственный опыт.

С контурами наверняка та же проблема, ты же передаёшь std::vector. Это легко проверить - перекомпилируй OpenCV и ошибки должны исчезнуть. С заголовком окна у меня так и было: взял изначальные dll - ошибка есть; перекомпилировал - исчезла. Впрочем, в отладчике тоже это видно - память затирается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

разбирался с компиляцией.. использую CMake по мануалу, затем sln в VS открываю и rebuild делаю. при компилировании появляются новые либы, которых нету в стандартной установке OpenCV_VS_2008 и dll тоже, при этом они появляются в подкаталоге Debug каталогов bin и lib, релизные версии не компилятся что ли? нужно ли из этого подгаталога переносить dll и lib с перезаписью в каталоги bin и lib?

во время плясок с бубном вспомнил, что в свойствах проекта в линкере добавил все libы и в Debug и в Release. попробовал оставить в Debug только либы с 'd' на конце имени файла, а в Release остальные. все заработало - и мавродиевские МMMM исчезли, и с векторами вроде проблемы кончились..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×