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

Nuzhny

Пользователи
  • Количество публикаций

    1 427
  • Зарегистрирован

  • Посещение

  • Days Won

    176

Сообщения, опубликованные пользователем Nuzhny


  1. здесь img_load_ch1 определен как std::deque<IplImage *> img_load_ch1; и в него добавлены исходные изображения

    При вычислении cvCalcEigenObjects возникает ошибка

    [C++ Error] Vision.cpp(575): E2034 Cannot convert '_STL::deque<_IplImage *,_STL::allocator<_IplImage *> >' to 'void *'

    [C++ Error] Vision.cpp(575): E2342 Type mismatch in parameter 'input' (wanted 'void *', got '_STL::deque<_IplImage *,_STL::allocator<_IplImage *> >')

    В cvCalcEigenObjects надо подавать два изображения, а ты подаёшь два массива с изображениями - несоответствие. Если ты хочешь работать с первыми элементами массивов, то пиши так:

    cvCalcEigenObjects(N_Samples, img_load_ch1[0], eig_img[0], CV_EIGOBJ_NO_CALLBACK, 0, 0, &Tc, mean_img, EigenVals->data.fl);

  2. Правильней будет создавать изображения стандартными средствами (cvCreateImage, cvLoadImage, ...) и хранить массив указателей. Например так:

    #include <deque>

    ...

    std::deque<IplImage *> images; //сам массив

    //Создаём и добавляем новый элемент

    IplImage *img = cvLoadImage("file.jpg");

    if (img)

    images.push_back(img);

    ...

    //Удаление всех изображений

    for (size_t i = 0; i < images.size(); ++i)

    {

    cvReleaseImage(&images);

    }

    images.clear();


  3. Захватить по цвету/текстуре получается? Если да, то найди основные моменты (cvMoments) и посмотри на их значения - возможно этого хватит для определения сжатой/несжатой ладони.


  4. Несоответствия типов там нет. Приведи лучше полный текст ошибки.

    Если же ты эту строку уберёшь, то, разумеется, появятся новые ошибки из-за обращения к пустому массиву по индексу - в него же ничего не добавляется.


  5. брр, что-то я запутался, как из этого значение цвета (0-255) получить :) Тип этой штуковины почему-то char*

    Если присвоить вот этот символ переменной типа int, получаю "0" для черных и "-1" для белых пикселей. Вроде совпадает, но как-то некрасиво получается :huh:

    Обычно сначала делают приведение к unsigned char:

    unsigned char *img_data = (unsigned char *)img->imageData;

    //А после уже

    img_data[x + y * img->widthStep]


  6. Сразу скажу, что не являюсь специалистом по распознаванию лиц. Но рассуждая логически, угол поворота лица можно узнать, зная расположение носа (рта, глаз, не важно, главное, чтобы можно было найти центр лица), а также границы лица. По расстояниям от центра лица до его краёв можно оценить угол поворота. Правда, подозреваю, что точность нахождения угла будет небольшой, зависит от расстояния до камеры.

    P.S. Идеальным вариантом представляется работа по стереоизображению.

    P.S2. Smorodov: мысль пришла одновременно.


  7. Фон отсекать как раз нельзя, каскад должен знать типичные отрицательные признаки. Грубо говоря, при проходе по каскаду подсчитывается сумма весов для каждой haar-feature. Значение очередной haar-feature сверяется с некоторым порогом. Если оно больше порога, то к сумме прибавляется один вес, если меньше - другой. Веса могут быть либо отрицательными, либо положительными в зависимости от того, удовлетворяет значение искомому объекту или нет. Веса и пороги формируются при обучении.

    Если ты затираешь фон, то значения весов, соответствующие ложной сработке, будут равны нулю (или почти нулю). А они должны быть отрицательными. Соответственно сумма всех весов будет больше, чем должна; отсюда ложные сработки.

    Следовательно, что для корректной работы необходимо выбрать большую выборку разнообразных положительных образов, а также большую выборку разнообразных отрицательных.


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

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


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

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

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


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


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

    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 столбца, один канал.

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


  12. Это в самой последней версии так сделано - ты имеенно её используешь?

    Я пока на 1.1 сижу - там OpenMP поддерживается. Хотя, зная политику Интела, использование TBB не должно быть медленней.

    Может быть ты в CMake не указал использование TBB?


  13. мля это полный ппц... даже если 2 сек на 1 картинку.. то 7000 объектов это 4 часа....
    Гхм!!! У нас ребята неделю сидели, выбирали.

    К примеру если я обучаю каскад на картинках 320x240, а использовать буду на 160х120
    Мой личный опыт (но никак не знание теории) подсказывает, что лучше обучать на минимальных объектах. Впрочем, здравый смысл говорит мне о том же.

  14. Это я понял, я в смысле, должно быть 7000 картинок с описаниями (0018.bmp 1 90 22 55 68) объектов?

    Должно быть 7000 объектов, а не картинок. А описаний столько, сколько самих картинок.

    Если на одном изображении присутствует, например 2 объекта, то описание будет выглядеть так:

    4_0344.bmp 2 295 153 9 17 349 153 10 18

  15. Это значит что должно быть столько картинок (7000, 3000)?
    Да, именно так.

    rawdata/0018.bmp 1 90 22 55 68

    rawdata/0019.bmp 1 81 19 59 76

    rawdata/0020.bmp 1 83 19 53 73

    Это означает, что на изображении 0018.bmp присутствует 1 искомый объект, причём его кординаты: x = 90, y = 22, width = 55, height = 68.

    Всё просто!


  16. Я в детали не вдавался, но стандартный пример blob_tracking работает, мягко говоря, не очень быстро. Особенно ужасными тормоза становятся при выставлении опции сопровождения CCMSPF.

    Приведённый RinOS пример, на первый взгляд, довольно неплох. Однако для него необходимо провести предварительную бинаризацию, что не всегда возможно. Например, при сопровождением лиц.


  17. Скорость разная на разных алгоритмах. Судя по официальной информации, максимальный прирост скорости наблюдается на медианном фильтре - 12 раз.

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

×