Jump to content
Compvision.ru
FormatCft

Как прикрутить OpenCV к билдеру?

Recommended Posts

А код можно посмотреть?

Конечно, завтра вечером после работы привезу,вроде спецциально ничего особо не изменял.

Share this post


Link to post
Share on other sites

#include <vcl.h>

#pragma hdrstop

# define _STLP_NO_CSTD_FUNCTION_IMPORTS

#define _FM_NO_REMAP

#include "cv.h"

#include "highgui.h"

#include "Unit1.h"

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

CvCapture* capture = 0;

int cam=0,camera=0;

int positionX=0;

int positionY=0;

IplImage *frame, *frame_copy = 0;

void ProcessFrame( IplImage* image, int z );

         int sizeX;//=Form1->Width ;

         int sizeY;//=Form1->Height ;

int Zapis;

boolean FlagMessag=false;


#define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)

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

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;

         }

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

void  APIDrawIpl(int x,int y,IplImage* _Grab,void *HANDLE)

{

HDC hMemDC,hDC;

hDC=GetDC(HANDLE);

hMemDC = CreateCompatibleDC(hDC);

HBITMAP Bitmap=CreateRGBBitmap(_Grab);

Bitmap=(HBITMAP)CopyImage(Bitmap,IMAGE_BITMAP,sizeX, // RESIZE

                     sizeY,LR_COPYDELETEORG);


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(camera);

Form1->Timer1->Enabled=true;

}

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

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

cvReleaseImage( &frame_copy );

cvReleaseCapture( &capture );

}

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

void ProcessFrame( IplImage* img,int z )

{

APIDrawIpl(0,0,img,Form1->Handle);

}


void __fastcall TForm1::FormResize(TObject *Sender)

{

         sizeX=Form1->Width ;

         sizeY=Form1->Height ;


}

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


void __fastcall TForm1::FormCreate(TObject *Sender)

{

Zapis=RegisterWindowMessage ("Zapis");


 for (int i= 0;  i < ParamCount(); i++)

   {

   if (ParamStr(i)=="size")

        {

         Form1->Width=StrToInt(ParamStr(i+1));

         Form1->Height=StrToInt(ParamStr(i+2));

         i=i+2;

        }

   if (ParamStr(i)=="cam")

        {

         cam=StrToInt(ParamStr(i+1));

         camera=StrToInt(ParamStr(i+1));

         i=i+1;

        }

   if (ParamStr(i)=="post")

        {

         Form1->Left=StrToInt(ParamStr(i+1));

         Form1->Top=StrToInt(ParamStr(i+2));

         i=i+2;

        }

   if (ParamStr(i)=="num")

        {

         i=i+1;

        }


   }


}

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


void __fastcall TForm1::FormActivate(TObject *Sender)

{

        if (FlagMessag==false)

        {

         Application->OnMessage = AppMessage;

         FlagMessag=true;

        }

}

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

void __fastcall TForm1::AppMessage(tagMSG &Msg, bool &Handled)

{

  if(Msg.hwnd)

  if(Msg.message==Zapis && Msg.wParam ==camera )

    {  //ShowMessage( camera+1);

      if (Form1->Tag==0)

      {

         if (Form1->N1->Checked==true )

                {

                 Form1->N1->Checked=false;

                }

                 else

                {

                 Form1->N1->Checked=true;

                }

      }

      Handled = true;

    }


}

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


void __fastcall TForm1::Timer1Timer(TObject *Sender)

{

    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 );


            if( frame->origin == IPL_ORIGIN_TL )

                cvCopy( frame, frame_copy, 0 );

            else

                cvFlip( frame, frame_copy, 0 );


            ProcessFrame( frame_copy,0 );

    }



skip:;


}

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

void __fastcall TForm1::N1Click(TObject *Sender)

{

 if (Form1->N1->Checked==true )

        {

         Form1->N1->Checked=false;

        }

        else

        {

         Form1->N1->Checked=true;

        }

}

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



Share this post


Link to post
Share on other sites

Так и знал :) таймер из компонентов. В таких вещах лучше использовать мультимедиа таймер (только осторожно, у него высокий приоритет), или обычный WinAPI-шный хотя-бы.

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

Есть хорошая книжка: Щупак "Win32 API. Эффективная разработка приложений".

Share this post


Link to post
Share on other sites

тогда вопрос: в чём отличие vcl таймера от WinAPI ?

почему всё жёстко висит даже если таймер 20 сек? вроде бы простой должен быть, а его нет :-\

Share this post


Link to post
Share on other sites

По поводу отличий не разбирался, знаю что у VCL свой поток, и с ним могут быть всякие неприятности.

Сделайте поток,

http://rxlib.ru/WinLesson/bles2_1.htm

внутри которого поместите Sleep. Sleep приостанавливает поток в котором выполняется на заданное время, и передает ресурсы другим потокам.

http://www.borlandtalk.com/image-vp78087.html

Share this post


Link to post
Share on other sites

Скачать версию 1.1pre1 и будет работать.

Для 2.0 и 2.1 тоже делал, где то было.

Для 2.3 и XE2 (тот-же билдер) тоже есть на форуме: http://www.compvision.ru/forum/index.php?showtopic=763.

для 2.4 не делал, там нужно заголовочные файлы править руками во многих местах.

При этом будет работать только C-шный интерфейс (cv::Mat и пр. работать без перестроики библиотек Borland-овским компилятором работать не будет).

Перекомпиляция борландом достаточно трудоемкий процесс, я не делал (хотя патч видел: http://code.opencv.org/issues/2057).

  • Like 1

Share this post


Link to post
Share on other sites

Сделал вывод на TPanel заработало, большое спасибо Smorodov'у. Но через некоторое время вылетает ошибка :angry:

"Bad argument(unrecognized or unsupported array type) in function cvReleseData, .\cxaray.cpp(1171)"

__fastcall Man_screen::Man_screen(bool CreateSuspended)

        : TThread(CreateSuspended)

{

FreeOnTerminate = true;

capture = cvCreateCameraCapture(0);

if(capture != NULL)

  {

   frame = NULL;

   scaled = NULL;

   sz.width=320;

   sz.height=240;

   scaled=cvCreateImage(sz,IPL_DEPTH_8U,3);

   cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX_SMALL, 1.0, 1.0);


  }


}

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

void __fastcall Man_screen::Execute()

{

if(capture == NULL)return;

while(man->work_man)

     {


      frame = cvQueryFrame(capture);

      cvResize(frame,scaled,CV_INTER_LINEAR);

      APIDrawIpl(scaled,Form1->Screen->Handle);

      //man->screen_ready=true;

      cvWaitKey(33);


     }

cvReleaseCapture(&capture);

cvReleaseImage( &frame);

}

Подскажите в чём дело?

  • Like 1

Share this post


Link to post
Share on other sites

Надо проверять frame после захвата, если NULL, то пропускать итерацию цикла.

и cvReleaseImage( &frame); не нужно скорее всего это и есть причина ошибки.

  • Like 1

Share this post


Link to post
Share on other sites

Добрый вечер! Из-за чего возникает подобная вещь? Уже третий день парюсь:

[C++ Fatal Error] Unit1.cpp(3): F1004 Internal compiler error at 0xc6a11c with base 0xc10000

  • Like 1

Share this post


Link to post
Share on other sites

А фрагмент кода можно посмотреть?

  • Like 1

Share this post


Link to post
Share on other sites

Здравствуйте... у меня немного "блондинистый" вопрос. :rolleyes: DLL в зоне видимости программы- это означает, что они должны быть в папке с проектом?

  • Like 1

Share this post


Link to post
Share on other sites

Где программа ищет DLL-ки:

1) Каталог запуска программы

2) Текущий каталог

3) System32

4) System

5) Windows

6) пути прописанные в переменной %PATH%

  • Like 1

Share this post


Link to post
Share on other sites

Hi all

Актуален ли еще вопрос в теме?

Дело в том ,что я в феврале 2016 начал компилить под embarcader XE файл  facedetect.cpp  и в прсессе этого прикрутил таки за неделю.

примерно 90 изменений примерно в 40 файлах - и всё.

Скомпилил все модули в либы. И теперь могу в любой проект с формами, базами и т.д. подцепить любые классы и фунуции OpenCV.

Если такое у вас уже есть, то извиняйте.

  • Like 1

Share this post


Link to post
Share on other sites

Да, я думаю актуален, народ частенько спрашивает об интеграции OpenCV и Builder.

Думаю подавляющее большинство отчаялось :)

  • Like 1

Share this post


Link to post
Share on other sites

1. У меня был скачан opencv-3.1.0.exe (115 129 966 байт длиной). Распаковываем куда-нибудь.
2. Оттуда 2 директория (build и sources) переносим в C:\Users\admin\PROGS\CV\. Это обязательно, т.к. в проектах билдера пути привязаны. Двигать будете, когда запустится.
3. Файл "1.rar" тоже с абсолютными путями. Его содержимое при копировании ложится в C:\Users\admin\PROGS\CV\.
4. Файл "2.rar" содержит путь к некоему заголовочному файлу и сам файл в среде Embarcadero RAD Studio XE. Его положить соответственно ваших путей с заменой устаревшего оригинала ...
5. После этого можно сразу загрузить группу проектов face_detector.groupproj. При запуске скомпилируются все нужные мне либы + facedetect.exe в C:\Users\admin\PROGS\CV1\LIBEXE\debug\.
6. Если последний запустить на выполнение прямо из IDE (Parameters уже в проекте) и положить в C:\Users\admin\PROGS\CV\ файл 2.jpg с групповым портретом вашей любимой компании, то у всей компании будут выделены лица и глаза в кружки. Или, если подключена камера, можно запустить, убрав Parameters...
facial_features_bcc.cpp - это немного доработанный оригинальный facial_features.cpp.
 
В папке haarcascades есть бонусы по сравнению с первоисточником.
 
Многие ( но не все ) места, где были внесены изменения в оригинальный текст, комментированы вот таким образом:
///ggg///
 
Из текста видно, что билдер мужик более простой и конкретный нежели MSВижуаллС++ :-)))
 
Dll-ки тоже можно стряпать, но OMF vs COFF при соучастии __stdcall и __cdecl так просто не сдадутся. )
 
При компилении очень важны Conditional defines в "Directories and Conditionals" из Options каждого проекта. Смотрите в каталогах - даю несколько готовых проектов для примера.

1.rar

2.rar

Инструкция по прикрутке.txt

  • Like 2

Share this post


Link to post
Share on other sites

ДУмается может Вам репозоторий соорудить на GitHub, думается народ потянется, может кто чего добавит или улучшит.

  • Like 1

Share this post


Link to post
Share on other sites

Здравствуйте в Builder 6 при создании приложения С использованием OpenCV получилось создать проект. Но при попытке сделать его переносимым

(то есть в

Options->PackagesBuild with runtime packages убираю галочку;

Options->Linker->Use dynamic RTL убираю галочку;

Options->Compiler->Release нажимаю на кнопку;

)

возникает ошибка нехватки  dll: CVHAARTRAINING.DLL; ILMIMF.DLL; ILMTHREAD.DLL; LIBPNG.DLL .

Подскажите как эту проблему можно решить.

Share this post


Link to post
Share on other sites
В 03.09.2016 at 18:29, Zaharov сказал:

1. У меня был скачан opencv-3.1.0.exe (115 129 966 байт длиной). Распаковываем куда-нибудь.
2. Оттуда 2 директория (build и sources) переносим в C:\Users\admin\PROGS\CV\. Это обязательно, т.к. в проектах билдера пути привязаны. Двигать будете, когда запустится.
3. Файл "1.rar" тоже с абсолютными путями. Его содержимое при копировании ложится в C:\Users\admin\PROGS\CV\.
4. Файл "2.rar" содержит путь к некоему заголовочному файлу и сам файл в среде Embarcadero RAD Studio XE. Его положить соответственно ваших путей с заменой устаревшего оригинала ...
5. После этого можно сразу загрузить группу проектов face_detector.groupproj. При запуске скомпилируются все нужные мне либы + facedetect.exe в C:\Users\admin\PROGS\CV1\LIBEXE\debug\.
6. Если последний запустить на выполнение прямо из IDE (Parameters уже в проекте) и положить в C:\Users\admin\PROGS\CV\ файл 2.jpg с групповым портретом вашей любимой компании, то у всей компании будут выделены лица и глаза в кружки. Или, если подключена камера, можно запустить, убрав Parameters...
facial_features_bcc.cpp - это немного доработанный оригинальный facial_features.cpp.
 
В папке haarcascades есть бонусы по сравнению с первоисточником.
 
Многие ( но не все ) места, где были внесены изменения в оригинальный текст, комментированы вот таким образом:
///ggg///
 
Из текста видно, что билдер мужик более простой и конкретный нежели MSВижуаллС++ :-)))
 
Dll-ки тоже можно стряпать, но OMF vs COFF при соучастии __stdcall и __cdecl так просто не сдадутся. )
 
При компилении очень важны Conditional defines в "Directories and Conditionals" из Options каждого проекта. Смотрите в каталогах - даю несколько готовых проектов для примера.

1.rar

2.rar

Инструкция по прикрутке.txt

 

в этом коментарии говорится о создании dll

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×