PixeLINK Frame Optimisation
Transcription
PixeLINK Frame Optimisation
ELVITEC Sas 139, rue Philippe de Girard 84 120 Pertuis France Tél : (33) 04 90 09 25 80 Fax : (33) 04 90 79 34 38 Web : www.elvitec.fr Email : [email protected] PixeLINK Frame Optimisation Version du document : 050507_000 Article Technique : OUI Application Démo : OUI Code Snippet : OUI Source Code(*) : OUI (* contrat Premium ) Résumé Documentation de fonctions optimisées de conversion des formats Pixel Téléchargements Inclus dans la DLL elv_PixelConvertDLL.dll Inclus dans la DLL elv_BayerDLL.dll Article Technique La CALL-BACK OVERLAY_FRAME met à disposition le buffer image reçu de la caméra avant toute conversion par la librairie PixeLINK. Le buffer image « brut » (RAW) doit alors être converti en un format de pixels utilisable par l'application. Les convertions les plus attendues sont [ le format RAW (Mono8 bits) étant directement utilisable]: RAW (Mono 10 bits) RAW (Bayer 8 ou 10 bits) RAW (YUV422) --> GRAY8 --> BGR24 --> BGR24 La librairie PixeLINK expose une fonction de converstion qui effectue ces opérations. C'est cette fonction de convertion qui aura été utilisée si on utilise une autre CALL-BACK que OVERLAY-FRAME. Les DLLs Utilitaires Elvitec exposent une API de fonctions optimisées qui permet une optimisation importante de ce processus , ce qui facilite la mise en oeuvre des algorithmes propres à l'application dans un contexte Machine Vision. Référence : caméra A782 en ROI 1024 x 768, shutter 86ms PC Shuttle Elvitec, P4 3Ghz HT Librairie PixeLINK mode YUV422 : environ 25% cpu avec display DLL Elvitec mode YUV422 : environ 5% cpu avec display Librarie PixeLINK mode BAYER8 DLL Elvitec mode BAYER8 Librarie PixeLINK mode BAYER16 DLL Elvitec mode BAYER16 : environ 20-24% cpu avec display : environ 2- 3% cpu avec display : environ 20-24% cpu avec display : environ 3- 4% cpu avec display Mise en place : Exemples : // ELVITEC UTILITY DLLs Elvitec Sas – Siret : 444 341 309 00011 – APE 721 Z #include "FastCopyDLL.h" #pragma comment(lib,"elv_FastCopyDLL.lib") #include "PixelConvertDLL.h" #pragma comment(lib,"elv_PixelConvertDLL.lib") #include "PixelProcessDLL.h" #pragma comment(lib,"elv_PixelProcessDLL.lib") #ifdef _TEST_NONE U32 __stdcall CallbackThread_Main(HANDLE hCamera, LPVOID pFrameData, U32 uDataFormat, PFRAME_DESC pDescriptor, LPVOID pContext) { CSpecificClass* pCamera = (CSpecificClass*)pContext; unsigned long size = 0; int Pitch = 0; if (pCamera) { size = min(pCamera->m_DibSize,pCamera->m_uFrameSize); Pitch= BytesPerLine(pCamera->Get_lSizeX(),8); MemcpyMMX2(pCamera->m_pImageHDC->GetDIBits(),(char*)pFrameData,size); // MISC TEST // image8_BinningAsResize // image8_Binning image8_Binning((unsigned char*)pCamera->m_pImageHDC->GetDIBits(), (unsigned char*)pFrameData, pCamera->Get_lSizeX(),pCamera->Get_lSizeY(), Pitch,Pitch,_NN); pCamera->m_FramesAcquired++; if (pCamera->m_hWnd) ::InvalidateRect(pCamera->m_hWnd,NULL,FALSE); } return ApiSuccess; } #endif #ifdef _TEST_BAYER U32 __stdcall CallbackThread_Main(HANDLE hCamera, LPVOID pFrameData, U32 uDataFormat, PFRAME_DESC pDescriptor, LPVOID pContext) { CSpecificClass* pCamera = (CSpecificClass*)pContext; if (pCamera) { if (pCamera->Get_lBitsPerPixel() == 16) { PxL_motorola2intelSSE((unsigned char*)pFrameData,pCamera->m_uFrameSize); pCamera->DoBayer16((unsigned char*)pCamera->m_pImageHDC->GetDIBits(), (unsigned char*)pFrameData); } else pCamera->DoBayer((unsigned char*)pCamera->m_pImageHDC->GetDIBits(), (unsigned char*)pFrameData); pCamera->m_FramesAcquired++; Elvitec Sas – Siret : 444 341 309 00011 – APE 721 Z if (pCamera->m_hWnd) ::InvalidateRect(pCamera->m_hWnd,NULL,FALSE); } return ApiSuccess; } #endif #ifdef _TEST_YUV U32 __stdcall CallbackThread_Main(HANDLE hCamera, LPVOID pFrameData, U32 uDataFormat, PFRAME_DESC pDescriptor, LPVOID pContext) { CSpecificClass* pCamera = (CSpecificClass*)pContext; if (pCamera) { pCamera->DoYUV422((unsigned char*)pCamera->m_pImageHDC->GetDIBits(), (unsigned char*)pFrameData); pCamera->m_FramesAcquired++; if (pCamera->m_hWnd) ::InvalidateRect(pCamera->m_hWnd,NULL,FALSE); } return ApiSuccess; } #endif void CSpecificClass::DoBayer(unsigned char* frame,unsigned char* pData) { int dibPitch = BytesPerLine(Get_lSizeX(),m_lBufferBitsPerPixel); if (m_lWB != 0) // white balance { double_t m_foffsetR = 0; double_t m_foffsetG = 0; double_t m_foffsetB = 0; double_t m_fgainR = 100; double_t m_fgainG = 100; double_t m_fgainB = 100; // reset first m_Bayer.ResetWhiteBalance(); m_Bayer.BAYERconvert(frame, (unsigned char*)pData, Get_lSizeX(),Get_lSizeY(), m_patternOrigin,0); m_Bayer.WhiteBalance(frame, Get_lSizeX()/2,Get_lSizeY()/2, dibPitch,1 , 1, &m_foffsetR, &m_foffsetG,&m_foffsetB, &m_fgainR,&m_fgainG,&m_fgainB,TRUE); // convert again after white balance m_Bayer.BAYERconvert(frame, (unsigned char*)pData, Get_lSizeX(),Get_lSizeY(), m_patternOrigin,0); InterlockedExchange(&m_lWB,0); } else m_Bayer.BAYERconvert(frame, (unsigned char*)pData, Get_lSizeX(),Get_lSizeY(), Elvitec Sas – Siret : 444 341 309 00011 – APE 721 Z m_patternOrigin,0); } void CSpecificClass::DoYUV422(unsigned char* frame,unsigned char* pData) { long dstmod = BytesPerLine(Get_lSizeX(),m_lBufferBitsPerPixel); long srcmod = BytesPerLine(Get_lSizeX(),8); convert_UYVYtoRGB24((void *)frame, (void *)pData, Get_lSizeX(),Get_lSizeY(),dstmod,srcmod); } Note sur le template YUV422 La caméra PixeLINK délivre un template YUV422 qui est du type canonique UYVY. Le type canonique alternatif est YUY2. YUY2 est généralement mieux supporté et sert plus généralement de base pour : l'overlay video sur les cartes graphiques modernes la base de transcodage vers YV12 (MPEG) l'optimisation de la compression JPEG ( YCbCr) Le transcodage UYVY <----> YUY2 est trivial puisqu'il suffit d'effectuer un SWAP, ce qui correspondrai, dans notre cas de figure, à ceci : motorola2intelSSE((unsigned char*)pFrameData,pCamera->m_uFrameSize << 1); Elvitec Sas – Siret : 444 341 309 00011 – APE 721 Z