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

Smorodov

Главные администраторы
  • Количество публикаций

    3 873
  • Зарегистрирован

  • Посещение

  • Days Won

    346

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


  1. Ну, неплохо было бы дать ссылку на оригинал: cvBlobsLib

    Она постоянно обновляется, причем достаточно деструктивно >_>

    Да, это она.

    Пришлось чуть подправить (возникало деление на ноль при поиске моментов (не проверялось условие равенства площади нулю), и чуть подрезать, чтобы билдер съел), а так вроде неплохо работает.


  2. Ага, похоже вы занимаетесь Automatic Image Annotation :(

    Есть, как минимум, один проект подобного рода на OpenCV Annotator, к сожалению без исходников.

    А почему вы используете Виола-Джонс? Этот алгоритм, похоже не самый популярный в данной задаче...

    Может отсюда что нибудь сгодится?

    Distinctive Image Features from Scale-Invariant Keypoints

    Вроде у них по образцу на примерах очень неплохо работает.

    ijcv04.jpg


  3. BlobsExample.jpg

    Пример с которого получен снимок : blobs_example.rar

    Библиотека для работы с блобами, взята у итальянцев, документацию перевожу.

    Комментарии на английском и итальянском. Как разберусь переведу. Пока так выкладываю: cvblobslib.rar


  4. Картинка в картинке (с поворотом и др. афинными преобразованиями) и вырезание прямоугольной области (с афинными преобразованиями)

    RectangleRegs.jpg

    Архив с проектом: PutImageROI.rar


  5. Хотелось бы использовать OpenCV в коммерческом продукте, из функционала понадобиться распознание наличия лица в кадре.

    Как быть с правами и лицензиями?! (нигде об этом ни строчки)

    PS только начал знакомиться с OpenCV (дня не прошло).

    На страничке wiki OpenCV написано "Может свободно использоваться в академических и коммерческих целях — распространяется в условиях лицензии BSD"

    Для справки:

    BSD (англ. Berkeley System Distribution) — система распространения программного обеспечения в исходных кодах, созданная для обмена опытом между учебными заведениями. Особенностью пакетов ПО BSD была специальная лицензия BSD, которую кратко можно охарактеризовать так: весь исходный код — собственность BSD, все правки — собственность их авторов.


  6. Детекторы кожи 3-шт. В исходнике нужный раскомментировать.

    SkinDetectors.jpg

    1) Skin Color Detection in (Cb, Cr) space по работам [1] и [2]:

    [1] R.L. Hsu, M. Abdel-Mottaleb, A.K. Jain, "Face Detection in Color Images,"

    IEEE Transactions on Pattern Analysis and Machine Intelligence ,vol. 24, no. 5,

    pp. 696-706, May, 2002. (Original)

    [2] P. Peer, J. Kovac, J. and F. Solina, Human skin colour

    clustering for face detection, In: submitted to EUROCON

    International Conference on Computer as a Tool , 2003. (Tuned)

    2) Гауссова модель

    3) По Пиру

    [1] P. Peer, J. Kovac, J. and F. Solina, Human skin colour

    clustering for face detection”, In: submitted to EUROCON

    International Conference on Computer as a Tool , 2003.

    (R>95)^(G>40)^(B>20)^(max{R,G,B}-min{R,G,B}>15)^(|R -G|>15)^(R>G)^(R>B);[/code]

    Комменты потом будут приделаны.

    Архив с проектом: SkinColorDetector.rar


  7. Наверное было-бы удобно все переводы разъясняющие работу с ОпенЦВ собрать в один архив, современем пользователей станет больше, надеюсь) тогда удобно будет что бы курс для начинающих был в одном месте, и он зайдя в этот раздел мог бы быстро посмотреть все примеры и найти нужную информацию.

    P.S. Вы один участвуете в развитие этого проекта?

    Обидно что у иностранцев руководство есть, а у нас нет, хотя ведь русские разрабатывали :(

    По поводу руководства, я так и собираюсь сделать, промежуточные результаты выражаются в двух файлах перевода справочника команд, которые выложены на сайте, по мере перевода буду в них добавлять материал. а вообще все, нужно структурировать, руководство допереводить, разбавить примерами и вообще довести до ума. Пока все бросаю на форум, оценить степень интереса к тем или иным темам, да и самому разобраться время нужно. На след. неделе время будет попробую что нибудь предварительное, из того что есть, сворганить. Работы еще лет на 100 :).

    Работаю пока один, еще один человек помог, это он форум поставил, правда сейчас он занят очень, проект сдает.


  8. Да уже решил, пришлось всё-таки добавить новый ForgroundDetector который ведёт статистику по маске а не для всего изображения, вообще большое неудобство что в OpenCV этого не оказалось, при этом они поддерживают трекинг объектов, но стоит объекту остановится гаусианы почти сразу его подминают подсебя)))

    Скоро у них релиз новой версии, думаю пожалуй стоит им отписаться пусть включат соответствующие изменения, тока я что-то не нашёл куда отсылать идеи по улучшению библиотеки, не подскажите?

    З.Ы. Темы такой нет, но во-первых хорошо что появился в рунете форум по опенцв, я всё ждал когда же на графиконе появится, но не судьба, во-вторых, если позволите, предложение - может стоит где-нибудь на сайте разместить ссылки на другие полезные ресурсы рунета, на тему ИИ, обработки графики, роботов, и.т.д.

    Вот что нашел:

    Идеи для новых версий (это wiki, и мне кажется, там надо просто вписать свои предложения): Страница для новых идей

    внизу страницы написано "Feel free to suggest your own ideas and the mentoring team will gladly look at them. Several other ideas are in this list: "

    PS: Этот сайт очень молодой, и пока я просто не успел всего что хотел, ссылки обязательно появятся, если есть предложения, присылайте, что считаете интересным и полезным, буду рад разместить их на главной странице в специальный блок.

    PS2: Со вторым FG детектором интересное решение, я бы не подумал об этом.


  9. Такой вопрос я в своём проекте использую BlobTracker. C гаусовым методом сбора статистики для фона.

    Его недостаток в том что довольно быстро блобы сливаются с фоном. Тем не мене для некоторых блобов этого хотелось бы избежать.

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

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

    Кто-нибудь сталкивался с таой задачей?

    Может быть добавить к методу сбора статистики выделение объекта по гистограмме, собираемой с блоба вначале, пока он движется, в смысле два параллельных процесса: один статистический, другой обратная проекция, как результат будет некоторое объединение (сумма, например). Но вопрос конечно интересный.


  10. Программка иллюстрирующая один из алгоритмов нахождения скелета изображения.

    Щелкаем мышкой по левой зеленой сетке (задаем исходное изображение), затем нажимаем "итерация 1", дальше "<-->", потом "итерация 2", "<-->", и сначала. Программка очень простая. Разобраться несложно. Для компиляции нужны компоненты со странички http://smorodov.narod.ru/Builder.htm.

    Архив с проектом: Skeletonizator.rar

    Skeletonizator.jpg


  11. как вывести полученный кадр с камеры?

    вот так получен

    IplImage* pFrame=cvQueryFrame(pCapture)

    а что с ним дальше делать

    функция cvShowImage не работает с IplImage

    и еще как создать окно (?cvNamedWindow) внутри другого (своего) окна?

    Вот это работает в C++Builder6. Архив с проектом: simple2.rar

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop

    #include "cv.h"
    #include "highgui.h"

    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    CvCapture* capture = 0;
    IplImage *frame, *frame_copy = 0;
    void ProcessFrame( IplImage* image );
    // Описатель шрифта (см. дальше)
    CvFont font;

    #define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)
    //---------------------------------------------------------------------------
    // Создание API шного битмапа из интеловского RGB изображения
    //---------------------------------------------------------------------------
    HBITMAP CreateRGBBitmap(IplImage* _Grab)
    {
    char *App;
    LPBITMAPINFO lpbi = new BITMAPINFO;
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbi->bmiHeader.biWidth = _Grab->width;
    lpbi->bmiHeader.biHeight =_Grab->height;
    lpbi->bmiHeader.biPlanes = 1;
    lpbi->bmiHeader.biBitCount = 24;
    lpbi->bmiHeader.biCompression = BI_RGB;
    lpbi->bmiHeader.biSizeImage = WIDTHBYTES((DWORD)_Grab->width * 8) * _Grab->height;
    lpbi->bmiHeader.biXPelsPerMeter = 0;
    lpbi->bmiHeader.biYPelsPerMeter = 0;
    lpbi->bmiHeader.biClrUsed = 0;
    lpbi->bmiHeader.biClrImportant = 0;
    void* pBits;
    HBITMAP hBitmap = CreateDIBSection(
    NULL,
    lpbi,
    DIB_RGB_COLORS,
    (void **)&pBits,
    NULL,
    0 );
    delete lpbi;
    if ( hBitmap )
    App=(char*)pBits;
    long int length=0;
    if(_Grab->nChannels==1) // Серое или бинарное
    {
    length = _Grab->width*(_Grab->height);

    for (int i=0;i<_Grab->height;i++)
    {
    for (int j=0;j<_Grab->width;j++)
    {
    App[_Grab->width*3*(_Grab->height-i-1)+j*3]=_Grab->imageData[_Grab->width*(i)+j];
    App[_Grab->width*3*(_Grab->height-i-1)+j*3+1]=_Grab->imageData[_Grab->width*(i)+j];
    App[_Grab->width*3*(_Grab->height-i-1)+j*3+2]=_Grab->imageData[_Grab->width*(i)+j];
    }
    }
    }
    if(_Grab->nChannels==3) // Цветное
    {
    for (int i=0;i<_Grab->height;i++)
    {
    memcpy(App+_Grab->width*3*(_Grab->height-i-1),_Grab->imageData+_Grab->width*3*i,_Grab->width*3); // Копируем память
    }

    }
    return hBitmap;
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    // Функция вывода изображения на HANDLE оконного компонента
    //---------------------------------------------------------------------------
    void APIDrawIpl(int x,int y,IplImage* _Grab,void *HANDLE)
    {
    HDC hMemDC,hDC;
    hDC=GetDC(HANDLE);
    hMemDC = CreateCompatibleDC(hDC);
    HBITMAP Bitmap=CreateRGBBitmap(_Grab);
    SelectObject(hMemDC,Bitmap);
    BitBlt(hDC,x,y,_Grab->width,_Grab->height,hMemDC,0,0,SRCCOPY);
    DeleteObject(Bitmap);
    DeleteDC(hMemDC);
    DeleteDC(hDC);
    }

    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------


    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    capture = cvCaptureFromCAM(0);
    // Инициализация шрифта (теперь можем вывести какой-нибудь текст)
    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,1,8);
    Application->OnIdle = IdleLoop; // Поток обработки простоя

    cvNamedWindow( "Window", 0 ); // Здесь создаем окно cvNamedWindow
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::IdleLoop(TObject*, bool& done)
    {
    done = false;// Поток обработки простоя
    if( capture )
    {
    if( !cvGrabFrame( capture ))
    goto skip;
    frame = cvRetrieveFrame( capture );
    if( !frame )
    goto skip;

    //*********************************************************
    // Если стерли то что ниже - это надо раскомментировать
    // if( !frame_copy )
    // frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
    // IPL_DEPTH_8U, frame->nChannels );
    // Делаем копию кадра, иначе может пропасть.
    // cvCopy( frame, frame_copy, 0 );
    // Если стерли то что ниже - это надо раскомментировать
    //*********************************************************

    //*********************************************************
    // Если не нужно подгонять размер кадра - это можно стереть
    // Выделяем память под копию кадра
    if( !frame_copy )
    frame_copy = cvCreateImage( cvSize(352,280),
    IPL_DEPTH_8U, frame->nChannels );
    // Масштабируем под заданный размер
    cvResize( frame, frame_copy, CV_INTER_LINEAR );
    // Если не нужно подгонять размер кадра - это можно стереть
    //*********************************************************

    cvShowImage( "Window", frame_copy ); // Здесь выводим в него IplImage


    ProcessFrame( frame_copy );
    }
    skip:;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    cvDestroyWindow( "Window" ); // Здесь его уничтожаем
    cvReleaseImage( &frame_copy );
    cvReleaseCapture( &capture );

    }
    //---------------------------------------------------------------------------
    void ProcessFrame( IplImage* img )
    {
    APIDrawIpl(10,10,img,Form1->Handle);
    }[/code]


  12. Все примеры скомпилированы на C++ Builder6 sp4 + OpenCV1.1pre1.

    Разрешение получаемого с моей видеокамеры изображения: 352х288 .

    При запуске с камерами бОльшего / меньшего разрешения получается небольшой (или большой) разъезд всего по форме.

    В некоторых примерах, где участвует статическая картинка возможна ошибка, связанная с несоответствием разрешения камеры этой картинке.

    Для решения проблемы:

    1 вариант) создайте в paint-е или еще где-нибудь картинку с разрешением Вашей камеры и бросьте в директорию с программой.

    2 вариант) Используйте информацию из поста о изменении размера изображения Этот пост или (лучше) ЭТОТ.

    Да и на всякий случай у меня программы лежат так : C:\Program Files\Borland\CBuilder6\Projects\NewCvPrograms\

    внутри этой директории находятся папки с программами.

    Уже исправлено.


  13. Все примеры скомпилированы на C++ Builder6 sp4 + OpenCV1.1pre1.

    Разрешение получаемого с моей видеокамеры изображения: 352х288 .

    При запуске с камерами бОльшего / меньшего разрешения получается небольшой (или большой) разъезд всего по форме.

    В некоторых примерах, где участвует статическая картинка возможна ошибка, связанная с несоответствием разрешения камеры этой картинке.

    Для решения проблемы:

    1 вариант) создайте в paint-е или еще где-нибудь картинку с разрешением Вашей камеры и бросьте в директорию с программой.

    2 вариант) Используйте информацию из поста о изменении размера изображения Этот пост или (лучше) ЭТОТ.

    Да и на всякий случай у меня программы лежат так : C:\Program Files\Borland\CBuilder6\Projects\NewCvPrograms\

    внутри этой директории находятся папки с программами.


  14. У меня такое компилируется.

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop

    #include "cv.h"
    #include "highgui.h"

    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    IplImage* img;
    void ProcessFrame( IplImage* img );
    #define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)
    //---------------------------------------------------------------------------
    // Создание API шного битмапа из интеловского RGB изображения
    //---------------------------------------------------------------------------
    HBITMAP CreateRGBBitmap(IplImage* _Grab)
    {
    char *App;
    LPBITMAPINFO lpbi = new BITMAPINFO;
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbi->bmiHeader.biWidth = _Grab->width;
    lpbi->bmiHeader.biHeight =_Grab->height;
    lpbi->bmiHeader.biPlanes = 1;
    lpbi->bmiHeader.biBitCount = 24;
    lpbi->bmiHeader.biCompression = BI_RGB;
    lpbi->bmiHeader.biSizeImage = WIDTHBYTES((DWORD)_Grab->width * 8) * _Grab->height;
    lpbi->bmiHeader.biXPelsPerMeter = 0;
    lpbi->bmiHeader.biYPelsPerMeter = 0;
    lpbi->bmiHeader.biClrUsed = 0;
    lpbi->bmiHeader.biClrImportant = 0;
    void* pBits;
    HBITMAP hBitmap = CreateDIBSection(
    NULL,
    lpbi,
    DIB_RGB_COLORS,
    (void **)&pBits,
    NULL,
    0 );
    delete lpbi;
    if ( hBitmap )
    App=(char*)pBits;
    long int length=0;
    if(_Grab->nChannels==1) // Серое или бинарное
    {
    length = _Grab->width*(_Grab->height);

    for (int i=0;i<_Grab->height;i++)
    {
    for (int j=0;j<_Grab->width;j++)
    {
    App[_Grab->width*3*(_Grab->height-i-1)+j*3]=_Grab->imageData[_Grab->width*(i)+j];
    App[_Grab->width*3*(_Grab->height-i-1)+j*3+1]=_Grab->imageData[_Grab->width*(i)+j];
    App[_Grab->width*3*(_Grab->height-i-1)+j*3+2]=_Grab->imageData[_Grab->width*(i)+j];
    }
    }
    }

    if(_Grab->nChannels==3) // Цветное
    {
    for (int i=0;i<_Grab->height;i++)
    {
    memcpy(App+_Grab->width*3*(_Grab->height-i-1),_Grab->imageData+_Grab->width*3*i,_Grab->width*3); // Копируем память
    }

    }
    return hBitmap;
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    // Функция вывода изображения на HANDLE оконного компонента
    //---------------------------------------------------------------------------
    void APIDrawIpl(int x,int y,IplImage* _Grab,void *HANDLE)
    {
    HDC hMemDC,hDC;
    hDC=GetDC(HANDLE);
    hMemDC = CreateCompatibleDC(hDC);
    HBITMAP Bitmap=CreateRGBBitmap(_Grab);
    SelectObject(hMemDC,Bitmap);
    BitBlt(hDC,x,y,_Grab->width,_Grab->height,hMemDC,0,0,SRCCOPY);
    DeleteObject(Bitmap);
    DeleteDC(hMemDC);
    DeleteDC(hDC);
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void ProcessFrame( IplImage* img )
    {
    APIDrawIpl(100,100,img,Form1->Handle);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    IplImage* gray;
    img = cvLoadImage("OpenCv.jpg");
    gray = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);
    cvCvtColor(img, gray, CV_BGR2GRAY); // Получаем серый цвет

    //****************************************************
    IplImage* resize;
    resize = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 1 /*3 - если цветное*/);
    // Масштабирование изображения
    cvResize( gray, resize, CV_INTER_LINEAR );
    //****************************************************

    ProcessFrame(resize);
    cvReleaseImage( &img );
    cvReleaseImage( &gray );
    cvReleaseImage( &resize );
    }
    //---------------------------------------------------------------------------[/code]


  15. // В пример для загрузки изображения вставить.

    IplImage* resize;

    // Создаем изображение нужного размера

    resize = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 1 /*3 - если цветное*/);

    // Масштабирование изображения - исходное изображение находится в gray

    cvResize( gray, resize, CV_INTER_LINEAR );

    // вместо CV_LINEAR возможны другие типы интерполяции:

    // CV_INTER_NN - nearest-neigbor interpolation (ближайший сосед ?)

    // CV_INTER_LINEAR - bilinear interpolation (билинейная - используется по умолчанию)

    // CV_INTER_AREA - resampling using pixel area relation. It is preferred method for image decimation that gives moire-free results. In case of zooming it is similar to CV_INTER_NN method. Масштабирование с учетом отношения пиксельных площадей. Наиболее предпочтительный метод, т.к. дает изображение без муара. Результат напоминает результат метода CV_INTER_NN.

    // CV_INTER_CUBIC - bicubic interpolation. Бикубичестая интерполяция.

    // Вывод или другое использование

    // Очистка

    cvReleaseImage( &resize );

×