CAFE

영상처리및제어

샘플-Basler GigE 카메라 영상 캡쳐하기 (OpenCV 사용안함)

작성자한창호|작성시간16.01.25|조회수11,613 목록 댓글 0

 Basler GigE Camera를 이용하여 영상을 캡쳐해보자

 

- Pylon Lib 설치방법:  https://cafe.daum.net/smhan/darS/3

 

* 샘플소스 코드:  수정함 (양진모학생 수정사항 적용함)

 

이번 소스에는 OpenCV를 사용하지 않고 pylon 라이브러리만 사용하여 영상처리를 한다.  내부 소스에서 bitmap을 처리하기 위해 모두 8bit 영상으로 바꾸어 처리한다. 처리하는 함수는 bmp.cpp/bmp.h에서 다룬다. 참고: bmp.cpp와 bmp.h를 사용할 때에 버그가 있을 수 있으니 SimpleBmp 클래스를 사용하길 바람 (안정적버전)

- 다음 소스코드는 vs2013버전에서 vs2023버전으로 변경한 코드이다.

 

 

* 프로젝트 작성 

단계예제 코드
Pylon Lib 설치https://cafe.daum.net/smhan/darS/3
프로젝트 생성프로젝트를 Dialog based로 생성한다.
BMP파일 추가bmp.cpp와 bmp.h

bmp 소스파일: https://cafe.daum.net/smhan/cczU/67
프로젝트 속성구성속성->VC++ 디렉터리 -> 포함 디렉터리
    $(PYLON_DEV_DIR)\include
 
구성속성->VC++ 디렉터리 -> 라이브러리 디렉터리
    $(PYLON_DEV_DIR)\lib\x64
전역변수와 함수를 선언한다.BOOL m_bThreadFlag;                                        // 쓰레드 루프 돌기
UINT ThreadImageCaptureFunc(LPVOID param);       // 쓰레드 함수
Image* m_Image;                                              // 화면에 그리는 영상 이미지
CInstantCamera *m_pCamera;                              // Basler Camera
CGrabResultPtr ptrGrabResult;      // This smart pointer will receive the grab result data.
초기화BOOL CbaslerCam2013Dlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    ...
    // TODO: 여기에 추가 초기화 작업을 추가합니다.
    
    PylonInitialize();
    CTlFactory& tlFactory = CTlFactory::GetInstance();
    DeviceInfoList_t devices;
    if (tlFactory.EnumerateDevices(devices) == 0)  {
        MessageBox(L"Basler Camera가 연결되지 않았습니다.");
    }
    else {
        // Create an instant camera object with the camera device found first.
        m_pCamera = new CInstantCamera(CTlFactory::GetInstance().CreateFirstDevice());
        INodeMap *m_pNodeMap; //GenericParameterAccess

        try
        {
            if (m_pCamera->IsOpen()) AfxMessageBox(_T("Camera is opened!"));
            else {
                //카메라 이벤트 처리가 먼저 활성화되어야합니다, 기본값은 꺼짐입니다.
                m_pCamera->GrabCameraEvents = true;
                // 카메라가 발견되었습니다. 생성하고 인스턴트 카메라의 객체에 연결합니다.
                m_pCamera->Attach(tlFactory.CreateDevice(devices[0]));

                if (m_pCamera->IsPylonDeviceAttached())
                {
                    m_pCamera->Open();

                    m_pCamera->MaxNumBuffer = 1;
                    m_pNodeMap = &m_pCamera->GetNodeMap();
                    CIntegerPtr offsetX(m_pNodeMap->GetNode("OffsetX"));
                    CIntegerPtr offsetY(m_pNodeMap->GetNode("OffsetY"));
                    CIntegerPtr width(m_pNodeMap->GetNode("Width"));
                    CIntegerPtr height(m_pNodeMap->GetNode("Height"));

                    int new_width = 1024;
                    int new_height = 624;

                    width->SetValue(new_width);
                    height->SetValue(new_height);
                    offsetX->SetValue((int)(new_width / 2));
                    offsetY->SetValue((int)(new_height / 2));

                    CString str;
                    str.Format(_T("Found camera: %s\nWidth: %d\nHeight: %d"),
                        CString(m_pCamera->GetDeviceInfo().GetModelName()),
                        width->GetValue(), height->GetValue());
                    AfxMessageBox(str);

                    m_pCamera->Close();
                }
            }
        }
        catch (GenICam::GenericException &e) //Error Handling
        {
            // Error handling
            CString strTrace;
            strTrace.Format(_T("Open_Camera - GenericException : %s\n"), (CString)e.GetDescription());
            AfxMessageBox(strTrace);
            return FALSE;
        }
    }

    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
화면출력void CbaslerCam2013Dlg::OnPaint()
{
    if (IsIconic())
    {
        ....
    }
    else 
    {
        CDialogEx::OnPaint();

        if (m_pImage != NULL) {

            // ---------------------------------------------------------------
            // 카메라에서 읽어들인 영상을 화면에 그리기
            // ---------------------------------------------------------------
            CRect rect;
            CDC* pDC;
            pDC = m_View.GetDC();
            m_View.GetClientRect(rect);
            DrawImage(&m_View, m_pImage);
            ReleaseDC(pDC);

            // ---------------------------------------------------------------------
            // 칼라영상을 이진화 한다.
            // ---------------------------------------------------------------------
            pDC = m_ViewBin.GetDC();
            m_ViewBin.GetClientRect(rect);

            Image* image2 = CreateImage(m_pImage->width, m_pImage->height);
            for (int y = 0; y < image2->height; y++) {
                for (int x = 0; x < image2->width; x++) {
                    if (m_pImage->imageData[y*m_pImage->width + x] > 100)
                        image2->imageData[y*m_pImage->width + x] = 255;
                    else
                        image2->imageData[y*m_pImage->width + x] = 0;
                }
            }
            DrawImage(&m_ViewBin, image2);
            FreeImage(image2);
            ReleaseDC(pDC);
            // ---------------------------------------------------------------

        }
    }
}
카메라 영상 캡처 시작 버튼을 누르면 쓰레드를 실행한다.void CbaslerCam2013Dlg::OnBnClickedCamStart()
{
 if (m_pCamera == NULL) {
  MessageBox(L"Basler Camera를 연결 후 다시 실행시켜주세요.");
  return;
 }
 m_pCamera->StartGrabbing( /*c_countOfImagesToGrab*/);
 m_bThreadFlag = TRUE;
 CWinThread *pThread = ::AfxBeginThread(ThreadImageCaptureFunc, this);
}
멈춤 버튼을 누르면 쓰레드 플래그를 false로 만들어 종료시킨다.void CbaslerCam2013Dlg::OnBnClickedCamStop()
{
 if (m_pCamera == NULL) {
  MessageBox(L"Basler Camera를 연결 후 다시 실행시켜주세요.");
  return;
 }
 m_pCamera->StopGrabbing();
 m_bThreadFlag = FALSE;
}
쓰레드 함수UINT ThreadImageCaptureFunc(LPVOID param)
{
    CbaslerCam2013Dlg *pDlg = (CbaslerCam2013Dlg *)param;
    if (m_pCamera == NULL) return 0;

    while (m_bThreadFlag)
    {
        // 영상 획득
        try  {
            if (m_pCamera->IsGrabbing())  {
                // Wait for an image and then retrieve it. A timeout of 5000 ms is used.
                m_pCamera->RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);

                if (ptrGrabResult->GrabSucceeded())  {
                    // Access the image data.
                    const uint8_t *pImageBuffer = (uint8_t *)ptrGrabResult->GetBuffer();
                    if (m_pImage == NULL) {
                        m_pImage = CreateImage(ptrGrabResult->GetWidth(), ptrGrabResult->GetHeight());
                    }
                    memcpy(m_pImage->imageData, pImageBuffer, ptrGrabResult->GetWidth() * ptrGrabResult->GetHeight());
                }
                else {
                    CString str;
                    str.Format(_T("Error: %d %s", 
                      CString(ptrGrabResult->GetErrorCode()), 
                      CString(ptrGrabResult->GetErrorDescription())) );
                    AfxMessageBox(str);
                }
                pDlg->Invalidate(FALSE);
            }
        }
        catch (GenICam::GenericException &e)
        {
            cerr << "An exception occurred. " << e.GetDescription() << endl;
        }
    }

    return 0;
}

 

 

 

 

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼