MIL 영상을 bmp로 취득 및 저장하는 방법 정리.

 

 

.h 선언

CDC                           *mp_memory_dc;

const int LIVE_IMAGE_PIXEL_SIZE_X = 1296;

const int LIVE_IMAGE_PIXEL_SIZE_Y = 976;

 

 

Cpp 생성부

mp_memory_dc       = new CDC();

 

=========================================================================================

           HDC h_dc = mp_memory_dc->GetSafeHdc();

 

           unsigned char *p_data = NULL;

           int width  = LIVE_IMAGE_PIXEL_SIZE_X;

           int height = LIVE_IMAGE_PIXEL_SIZE_Y;

 

           ////////////////////////////////////////

           BITMAPINFO l_bmp_info;

           l_bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

           l_bmp_info.bmiHeader.biWidth = width;

           l_bmp_info.bmiHeader.biHeight = height * -1;

           l_bmp_info.bmiHeader.biPlanes = 1;

           l_bmp_info.bmiHeader.biBitCount = 24;

           l_bmp_info.bmiHeader.biCompression = BI_RGB;

           l_bmp_info.bmiHeader.biSizeImage = (((width * 24 + 31) & ~31) >> 3) * height;

           l_bmp_info.bmiHeader.biXPelsPerMeter = 0;

           l_bmp_info.bmiHeader.biYPelsPerMeter = 0;

           l_bmp_info.bmiHeader.biClrImportant = 0;

           l_bmp_info.bmiHeader.biClrUsed = 0;

          

           HBITMAP h_bitmap = ::CreateDIBSection(h_dc, &l_bmp_info, DIB_RGB_COLORS, (void **)&p_data, NULL, NULL);

           HDC h_mem_dc = ::CreateCompatibleDC(h_dc);

           HBITMAP h_old_bitmap = (HBITMAP)::SelectObject(h_mem_dc, h_bitmap);

 

           unsigned char *pTemp;

           pTemp = new unsigned char[width*height*3];

 

  // MIL 함수에서 현재 영상을 pTemp에 담음.

MbufGetColor(m_MilIdImg_Live, M_PACKED+M_BGR24   , M_ALL_BANDS, pTemp);

 

           memcpy(p_data, pTemp, width*height*3);

 

           RECT rect;

           rect.right = LIVE_IMAGE_PIXEL_SIZE_X;

           rect.bottom = LIVE_IMAGE_PIXEL_SIZE_Y;

           rect.left = 50;

           rect.top = LIVE_IMAGE_PIXEL_SIZE_Y-50;

 

           ::SetTextColor(h_mem_dc, RGB(255,0,0));

           ::DrawText(h_mem_dc, szOverlayText,strlen(szOverlayText), &rect, DT_LEFT);

           memcpy(pTemp, p_data, width*height*3);

          

// 저장된 pTemp 영상 이런저런 처리 후 MIL에 다시 집어넣기

if(pTemp)

{

           MbufPutColor(m_MilIdImg_Grab,M_PACKED+M_BGR24   , M_ALL_BANDS, pTemp);

           MbufCopyColor2d(m_MilIdImg_Grab,         m_MilIdImg_ForJudge, M_ALL_BANDS,

                     0, 0, M_ALL_BANDS, m_nLiveImageSizeX,0,m_nLiveImageSizeX, m_nLiveImageSizeY);

}

else

{

           MbufCopy(m_MilIdImg_Live, m_MilIdImg_Grab);

           MbufCopyColor2d(m_MilIdImg_Grab,         m_MilIdImg_ForJudge, M_ALL_BANDS,

                     0, 0, M_ALL_BANDS, m_nLiveImageSizeX,0,m_nLiveImageSizeX, m_nLiveImageSizeY);

}

          

           delete [] pTemp;

 

           ::SelectObject(h_mem_dc, h_old_bitmap);

           ::DeleteObject(h_bitmap);

           ::DeleteDC(h_mem_dc);

=========================================================================================

 

Mil 9.0 MdigFocus 활용 방법입니다.

Mil 9.0 Full version을 사용해야 MdigFocus 기능 사용이 가능합니다.

 

===================================================================================================

MIL_INT Focus_Indicator_Value; // Focus_Indicator_Value (이미지 초점 품질 척도값).

 

for (MIL_INT i= FocusMinPosition; i<=FocusMaxPosition; i++)
{

j++;

 

imageLoad((int) i); // 이미지를 불러온다

 

MdigFocus( // evalution 값만 불러와서 출력한다.

M_NULL,
MilImage,
M_DEFAULT,
NULL,
NULL,
FocusMinPosition,
i,
FocusMaxPosition,
M_DEFAULT,
M_EVALUATE,
&Focus_Indicator_Value

);

}

 


 

 

하기 소스 중 붉은 색 부분 참조해주세요.

int CLiveCamera::m_fnCamInit(_ST_INITDESC_LIVECAM *pInitDesc)

{

..............

//Allocate
char szDCFFile[MAX_PATH] = {0,};
sprintf(szDCFFile, "C:\\SolXCL_FD202SCL_c_24bit_72_16d.dcf");

MdigAlloc(m_MilIdSys, M_DEV0, (MIL_TEXT_PTR)szDCFFile, M_DEFAULT, &m_MilIdDig);

if(m_MilIdDig == M_NULL)
{
if(m_MilIdImg) { MbufFree(m_MilIdImg); m_MilIdImg = NULL; }
if(m_MilIdDig) { MdigFree(m_MilIdDig); m_MilIdDig = NULL; }
if(m_MilIdDisp){ MdispFree(m_MilIdDisp); m_MilIdDisp = NULL; }
if(m_MilIdSys) { MsysFree(m_MilIdSys); m_MilIdSys = NULL; }
if(m_MilIdApp) { MappFree(m_MilIdApp); m_MilIdApp = NULL; }
return -1;
}

디지타이저 생성 후 옵션에 따라 선택...

//////////////////////////////////////////////////////////////
//MdigControl(m_MilIdDig, M_GRAB_DIRECTION_X, M_REVERSE);

//MdigControl(m_MilIdDig, M_GRAB_DIRECTION_Y, M_REVERSE);
//////////////////////////////////////////////////////////////


//a MdigControl(m_MilIdDig,M_GRAB_MODE,M_ASYNCHRONOUS); //
반드시 M_ASYNCHRONOUS
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Allocate Buffer
// long band = MdigInquire(m_MilIdDig, M_SIZE_BAND, M_NULL);


MbufAllocColor(m_MilIdSys, 3, m_nGrabSizeX, m_nGrabSizeY, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &m_MilIdImg);

MbufAllocColor(m_MilIdSys, 3, m_nGrabSizeX, m_nGrabSizeY, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &(m_MilIdImgField[0]));
MbufAllocColor(m_MilIdSys, 3, m_nGrabSizeX, m_nGrabSizeY, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &(m_MilIdImgField[1]));

....................

}

 

// Allocate a MIL application.
MIL.MsysAlloc("M_DEFAULT", MIL.M_DEFAULT, MIL.M_DEFAULT, ref _milSysId);

// Allocate a MIL display.
MIL.MdispAlloc(_milSysId, MIL.M_DEFAULT, "M_DEFAULT", MIL.M_WINDOWED, ref _milDispId);

// License 정보를 확인한다.

// 취득데이터 : License가 있는경우 0 이외의 값이 리턴.

License가 없는경우 0 값이 리턴.
MIL_INT test = MIL.MsysInquire(_milSysId, MIL.M_LICENSE_MODULES);

 

C# 영상처리 소스 (panel에 출력)

picture box에 출력하니 오버랩이 심햇다.

하지만. panel에 출력하니 그러한 현상이 사라졌다. 아싸ㅓ~!!!

 

C type의 소스를 C#으로 변경중 하기 HookFunction을 어떻게 처리해야 하는지 고민하다..

알게된 사실... 2번째 인자를 이벤트로 처리해서 MappHookFunction 발생시 연결된

이벤트가 호출되도록 하면 된다는것..

 

MIL.MappHookFunction(MIL.M_ERROR_CURRENT, DisplayDrv_eDisplayErrorExt, MIL.M_NULL);

 

상기 함수의 원형은 이렇다.

///////////////////////////////////////////////////////////////////////////

void MappHookFunction(

MIL_APP_HOOK_FUNCTION_PTR HookHandlerPtr,

)

///////////////////////////////////////////////////////////////////////////

여기서, MIL_APP_HOOK_FUNCTION_PTR 의 원형은 이렇다.

///////////////////////////////////////////////////////////////////////////

namespace Matrox.MatroxImagingLibrary
{
public delegate MIL_INT MIL_APP_HOOK_FUNCTION_PTR
(

MIL_INT HookType,

MIL_ID EventId,

IntPtr UserDataPtr );

}

///////////////////////////////////////////////////////////////////////////

즉, delegate로 선언되어있기때문에, event로 인스턴스 선언하고 event 등록시키면 된다.

요렇게..

선언.

public event MIL_APP_HOOK_FUNCTION_PTR eDisplayErrorExt;

처음 로딩되는 부분에서 이벤트 등록

eDisplayErrorExt += new MIL_APP_HOOK_FUNCTION_PTR(DisplayDrv_eDisplayErrorExt);

실제 사용하는 부분

// user-defined function to a specified application event

MIL.MappHookFunction (

MIL.M_ERROR_CURRENT,

DisplayDrv_eDisplayErrorExt,

MIL.M_NULL );

hook 발생시 실행되는 함수 원형

// MIL Application Hooking Function(event-function)
MIL_INT DisplayDrv_eDisplayErrorExt(MIL_INT HookType, MIL_ID EventId, IntPtr UserDataPtr) {
StringBuilder szbFunction = new StringBuilder(MIL.M_ERROR_MESSAGE_SIZE);
// M_CURRENT_FCT : Returns the opcode associated with the last function

called, when it returns an error.
MIL.MappGetHookInfo(EventId,

MIL.M_MESSAGE + MIL.M_CURRENT_FCT,

szbFunction );

return MIL.M_NULL;

}

MIL 9.0 사용하다가 발생된 에러인데,,

원인은 이렇다.

 

현재 MIL 9.0 설치 PC: Matrox MIL 9.0 Lite 64bit

개발 환경 : VS2010에서 C#으로 MIL 9.0 Class Library 형태로 제작(flatform: any)

MIL 9.0 Library 사용 Application 빌드 환경 : X86..

--> X86 환경으로 되어있어 하기와 같은 문제가 발생하였다.

 

 

해서 X86부분을 AnyCpu 로 변경하니 정상 동작되었다.

 

단 MIL 9.0 32bit 버젼이면 상관없을 듯 하다.

'영상처리 > MIL' 카테고리의 다른 글

C# 영상처리 소스 (panel에 출력)  (1) 2014.01.17
C# MIL MappHookFunction 처리하기  (0) 2014.01.17
Bayer Filter 내용  (1) 2014.01.17
2중 선형 보간법(bilinear Interpolation)  (0) 2014.01.17
3CCD Camera 사용  (0) 2014.01.17

하기 사이트에서 참고함.

발췌: http://blog.naver.com/suyguy17?Redirect=Log&logNo=138603366

출처] 2중 선형 보간법(bilinear Interpolation)|작성자 배트맨

MBufBayer 의 옵션중하나로써,

2중 선형 보간법(bilinear Interpolation)사각형의 네끝점의 값만 알고 있을 경우,

 

사각형 내부의 임의의 위치에서의 값을 알아내는데 사용되는 계산 방법이다.

 

2중 선형 보간법(bilinear Interpolation)에 대한 자료를 인터넷에서 검색하니 영문자료 밖에 없어서

일단 여기에 이해하기 쉽게 정리해 본다.

 

2중 선형보간법은 선형보간법을 2중으로 사용하여 계산하는 방법이므로,

이해를 위해서는 먼저 선형보간법(Linear Interpolation)을 알아야 한다.

 

선형보간법의 경우는 단순히 직선상의 두점 사이의 임의 위치에서의 값을 계산해내는 것이라면,

2중 선형 보간법은 평면을 이루는 네 꼭지점안에 있는 임의의 위치에서의 값을 계산해내는 방법이다.

 

그림으로 설명하자면,

 

 

위의 그림의 경우,

사각형 모서리의 끝점 Q11, Q12, Q21, Q22 4개의 값만 알고 있다고 가정했을 때...

그 사각형 사이의 임의의 위치에서는 어떤 값이 될까?

 

일단 계산 개념은 아래와 같이 간단하다.

 

1. Q11과 Q21 두점 사이에 있는 R1의 값을 선형보간법을 사용하여 알아낸다.

2. Q12과 Q22 두점 사이에 있는 R2의 값을 선형보간법을 사용하여 알아낸다.

3. R1과 R2 두점 사이에 있는 P의 값을 선형보간법을 사용하여 알아낸다.

 

Visual Studio 2005로 제작된 C++ 샘플도 첨부하니 참고하기 바란다.

 

'영상처리 > MIL' 카테고리의 다른 글

C# 영상처리 소스 (panel에 출력)  (1) 2014.01.17
C# MIL MappHookFunction 처리하기  (0) 2014.01.17
MIL 9.0 Error : Matrox.MatroxImagingLibrary 로드 에러  (0) 2014.01.17
Bayer Filter 내용  (1) 2014.01.17
3CCD Camera 사용  (0) 2014.01.17

목적: Hitachi CCD Camera 사용(FD-202SCL)

원인: 본 카메라는 3CCD Camera로써, BayFilger가 존재하지 않지만,

해당 소스에서 BayBuf를 사용하여 흑백으로 화면이 표시됨.

해결: MbufBayer -> 사용하지 않음

 

문제부 소스

////////////////////////////////////////////////////////////////////////////////////////////////

// FD-202SCL is 3CCD Camera system. It has a 3CCD Camera type. So It haven't bayer filter.
// If you want to use for your ccd image, you don't need to MBufBayer function in MIL Library.
#ifdef _FD_202SCL_HITACHI_CCD_CAMERA
// not use.
#else
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType+M_WHITE_BALANCE_CALCULATE);
EnterCriticalSection(&g_csWhiteBalance);

#ifdef _MIL_90
if(pDlg->m_bUse_AVERAGE_2X2)
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType/* +M_AVERAGE_2X2*/);
else
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType +M_ADAPTIVE);
#else
MbufBayer(pDlg->m_MilIdImgField[g_nBufCpyIndex],pDlg->m_MilIdImg, pDlg->m_MilIdWBCoefficients, pDlg->ConversionType +M_ADAPTIVE);
#endif
LeaveCriticalSection(&g_csWhiteBalance);
#endif

/////////////////////////////////////////////////////////////////////////////////////////////////////////

 

해당 소스부 .h

1. MIL_ID m_MilIdImg; // Image buffer identifier

 

.cpp

m_MilIdImg = M_NULL; // Image buffer identifier

MbufClear(m_MilIdImg, 0);

 

// Solios 사용.

pSystem = "\\\\.\\M_SYSTEM_SOLIOS ;

 

// Main Mil Sys 할당

MsysAlloc((char*)pSystem, M_DEF_SYSTEM_NUM, M_COMPLETE | M_DDRAW, &m_MilIdSys);

 

MdigControl(m_MilIdDig, M_GRAB_MODE, M_ASYNCHRONOUS); //must M_ASYNCHRONOUS

MdigControl(m_MilIdDig, M_GRAB_TIMEOUT , 1000);

 

MdigHookFunction(m_MilIdDig, M_GRAB_START, HookFrameEnd, (void *)(this)); // 데이터 취득 함수설정
MdigHookFunction(m_MilIdDig, M_GRAB_END, HookGrabEnd, (void *)(this)); // 취득 함수 설정

 

// 3 band (r,G,B) grab x/y size 설정, MildImg 저장.

MbufAllocColor(m_MilIdSys, 3, m_nGrabSizeX, m_nGrabSizeY, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &m_MilIdImg);

 

//Allocate from dcf file. szDCFFile = Camera 사용 DCF files.
MdigAlloc(m_MilIdSys, M_DEFAULT, (MIL_TEXT_PTR)szDCFFile, M_DEFAULT, &m_MilIdDig);

 

// band acquire

long band ;
band = MdigInquire(m_MilIdDig, M_SIZE_BAND, M_NULL);

 

// mil 데이터 취득.

#ifdef _FD_202SCL_HITACHI_CCD_CAMERA
MdigGrab(pDlg->m_MilIdDig, pDlg->m_MilIdImg);
#else
MdigGrab(pDlg->m_MilIdDig, pDlg->m_MilIdImgField[g_nBufIndex]);
#endif

+ Recent posts