저번 리뷰(About Grabber(2)) 에 이어서 Grabber Manual을 위한 정리를 작성했습니다.
목차 (작성하며 변경예정)
1. Multi-spectral Grabber
2. QT
3. Ebus SDK
4. Code Review
2. QT
2.1 QT 란
QT는 기본언어를 c++로하는 GUI제작용 크로스플랫폼프레임워크입니다. QT는 C++을 주로 사용하지만, 파이썬, 루비, C펄, 파스칼과도 연동됩니다. 수많은 플랫폼(Windows, Linux,Mac 등) 에서 사용가능 하다는 장점은 저희가 QT를 선택한 가장 큰 이유이며 다른 GUI 개발자가 QT를 선택하는 이유이기도합니다.
Ebus SDK가 Window와 Linux 전부 지원하고 각 OS 환경에 따라서 할 수 있는 일이 다르기 때문에 저희는 두 OS 환경에서 Grabber가 동작할 수 있도록 QT를 선택했습니다. 또한 두 OS를 전부 다뤘기 때문에 두 OS에 따라서 다른 부분을 따로 나눠서 다뤄 보도록 하겠습니다.
2.2 QT 설치
2.2.1 QT 설치(Window)
Window에서 QT설치는 이 블로그를 참고했습니다.
Window에서 QT를 사용하기 위해서는 먼저 코드 컴파일을 위해서 Visual Studo를 깔아야합니다. Visual Studio는 Ebus SDK와의 호환성을 위해서 2015버전을 깔아야하며, 만약 그 윗버전을 깔았다면 2015버전의 컴파일러까지 추가 옵션으로 다운 받으셔야합니다. (2017버전에서는 2015버전의 컴파일러를 깔 수 있는 것을 확인했지만 그 이후의 버전은 아직 확인되지 않았습니다.) 또한 MFC 관련 빌드 도구를 다운 받아야지 제대로 컴파일을 할 수 있으며 필요한 추가 다운로드 옵션을 그림 1에서 확인할 수 있습니다.
컴파일러를 다운로드 받았다면 이제 QT를 다운받아야하는데요 QT는 이 링크를 이용해서 다운 받으며, 내리다보면 위 그림과 같이 open source user를 위한 다운로드 링크를 있으며 그것을 클릭 하시면 됩니다.
그림 2을 속 링크를 클릭 시 나오는 화면을 쭉 내리면 그림 3과 같이 나오며, 그림 3 속 버튼을 누르면 installer download 용 버튼이 나오는데 그것을 클릭해서 installer를 다운시길 바랍니다.
installer를 다운로드 받은 후 실행시키면 그림 4과 같은 화면이 뜨며 log in 하라고 나옵니다. 아이디가 없다면 만드시고 다음으로 진행하면 됩니다.
그림 4에서 Next를 누르다보면 그림 5와 그림 6같은 체크박스가 나옵니다. 이때 그림과 같이 체크를 해주시고 Next를 누릅시다.
Next를 누르시다보면 그림 7과 같이 경로 설정 하는 창이 나옵니다. 이때 원하시는 경로로 설정해주시고 꼭 Custom installation 을 누르시길 바랍니다.
마지막으로 그림8과 같이 설정해주시고 Next를 누르면 QT 다운로드가 시작되며 다운로드가 완료되면 QT 설치가 완료됩니다.
2.2.2 QT 설치(Ubuntu)
우분투에서 QT 설치는 이 블로그를 참고하시고, 이미 저희 모든 Jetson nano나 Xavier에 QT가 깔려있기 때문에 자세한 설명은 생략하도록 하겠습니다.
2.3 QT 시작하기
코드 제작은 QT creator에서 합니다. 따라서 QT를 시작하기 위해서 QT 다운로드하며 같이 깔린 QT creator를 실행시켜주시면 됩니다.
QT creator를 실행시키면 그림 9와 같은 화면이 나옵니다.
이제 프로젝트를 생성하기 위해 가운데 상단에 Project 옆 New를 클릭해줍니다.
QT를 이용해서 GUI를 제작하기 위해서 그림 10과 같이 QT Widgets Application을 골라주시면 됩니다. 다음으로 그림 11과 같이 Project 이름와 경로 설정이 나오며, 원하는 상황에 맞게끔 설정해수길 바랍니다. 그 후엔 Next를 계속 누르시면 됩니다.
마지막으로 code 실행을 위한 툴을 선택하는 창이 그림 12와 같이 나오며 이때는 Desktop QT 5.15.2 MSVC2015 64bit를 선택해주시고 Next를 누르면 project 생성이 완료됩니다.
2.4 QT를 이용해 원하는 GUI 제작하기, 참고: 블로그
QT를 이용해서 GUI를 제작해서 원하는 알고리즘을 수행하도록 하기 위해서는, 먼저 QT Designer를 이용해 GUI를 제작한 이 후 내부 알고리즘을 작성하면됩니다.
QT Designer를 이용한 제작하는 과정은 한번 배우면 매우 쉽습니다.
먼저 Project 생성이후 가장 먼저 그림 13과 같은 창이 뜰 것이며, 그때 그림 13 속 화살표가 가리키는 mainwindow.ui를 누르면 그림 14와 같이 GUI를 제작할 수 있는 QT Designer 로 갈 수 있습니다.
그림 14 속 파란 박스들을 간단히 정리하면 다음과 같습니다.
제작용 툴 모음: GUI 제작작가 사용할 수 있는 GUI 속 툴 모음입니다. 이 속에는 button, Display 화면, Text brower, Slider 등 다양한 툴이 있어서 사용자가 상황에 맞게끔 custom 할 수 있도록 합니다.
GUI: 이 GUI는 사용자가 실제 제작하고 있는 화면 입니다. 따라서 만약 옆 툴 모음에서 button을 끌어다가 놓으면 실제 제작하고 있는 GUI에 button이 생성되는 형식입니다.
GUI 정보: 제작자가 GUI에 올려놓은 제작용 툴이 어떤것이 있는지와 각 툴의 변수명이 무엇인지 알 수 있으며 이곳에서 각 툴의 변수명을 변경할 수도 있습니다.
제작용 툴 상세정보: GUI에 올려놓은 툴의 상세정보를 볼 수 있는 곳입니다. 이곳에서 또한 툴의 변수명과 display 명을 변경할 수 있으며 그 외에도 크기나 폰트 등 다양한 설정값을 변경할 수 있습니다.
예제를 통해서 QT GUI제작으 알아보도록 하겠습니다. 먼저 저는 그림 15와 같이 계산기를 제작했는데요.
제작 방식은 매우 간단합니다. 왼쪽에 있는 Push Button을 클릭한 후 GUI에 끌어다 놓으면 됩니다. 그리고 요기서 위에 text 가 들어갈 Tool은 Text Edit을 끌어다 놨습니다.
Tool들을 다 옮긴 후 옮긴 Tool의 변수명과 Display 명을 바꿔야 합니다. 먼저 Display 명은 사용자에게 이 버튼이 무엇인지 알려주기 위해서 변경해야하며, 변수명은 제작자가 이 Tool을 사용할때 원하는 변수명으로 바뀌어 있어야 사용할때 용이하기 때문에 변경해야합니다. 저는 계산기에서 1에 해당하는 버튼을 생성했으므로 각각을 그림 17과 같이 설정했으며 모든 버튼을 각 기능에 맞게 다 변경해주시면 됩니다.
그 다음 이 버튼이 눌러졌을 때 작동할 함수를 생성해줘야합니다. 함수 생성을 위해서 버튼을 마우스로 갖다댄 후 오른쪽 클릭한 후 Go To Slot을 클릭하면 어떤 행동에 대한 함수를 생성할지 선택하는 창이 뜹니다. 저는 단순히 클릭할 경우 1을 계산기에 입력으로 넣는 것이니 click()을 선택한 후 OK를 선택했습니다.
click() 를 선택하면 그림 19와 같이 Mainwindow.cpp와 mainwindow.h에 on_변수명_clicked() 함수가 생성되며 mainwindow.cpp 속 함수에 작성된 알고리즘이 button이 클릭됐을때 실행됩니다.
그림 20과 같이 코드를 작성하면, clilck했을때 제가 만들어둔 textEdit 변수명을 가진 text display tool에 1 추가적으로 출력됩니다. 이때 qstr을 전역변수로 설정된 QString 변수이며 0~9까지 그리고 연산기호까지 동일한 방식으로 만들어준 후 ‘=’ 버튼을 눌렀을때 qstr에 저장된 계산식을 토대로 계산하는 알고리즘을 작성하면 계산기가 완성됩니다.
2.4.1 QThread를 이용한 예시 추가 예정
2.5 QT에 Library 연결하기
Camera Grabber를 제작하기 위해서는 총 두가지 라이브러리가 필요합니다. Opencv 와 Ebus SDK가 그 라이브러리인데요. 먼저 OpenCV는 대표적인 영상처리용 라이브러리로 받아온 영상의 크기를 변환하거나 type을 변환하는 등 다양한 이유로 사용되고 있습니다. 그리고 Ebus SDK 는 저희가 사용하는 카메라로부터 영상을 받기위해서는 반드시 필요한 라이브러리이며 자세한 설명은 Section 3에서 추가적으로 하겠습니다.
두가지 라이브러리를 코드에서 사용하기 위해선 추가적인 작업이 필요합니다.
이 라이브러리를 제대로 QT에 연동하기 위해서는 원래는 라이브러리를 다운받고 CMake나 QMake를 해야하는 등 꽤 어려운 작업이 필요하지만 그런거 할 필요없게 이 링크 에 라이브러리들을 제공합니다. (Window 용, Ubuntu는 이미 연구실에 있는 모든 장비에 다 깔려있음) 라이브러리를 다운 받은 후 압축을 원하는 경로에 풀어줍니다.
이제 제가 할 작업은 QT에 압축 푼 라이브러리의 경로를 추가해서 QT에서 이 라이브러리를 사용할 수 있도록 하는 것입니다.
먼저 QT에 어떠한 것의 경로를 추가하느냐인데요. 저희가 추가할 경로는 총 세가지 입니다. 그 세가지는 dll,lib, .h 파일 인데요. 각각 어떠한 역할을 하는 지는 이 블로그를 찾아보시면 될 것 같습니다.
이제 총 세가지의 파일 경로를 어떻게 추가하는지 설명하도록 하겠습니다.
먼저 QT 프로젝트에 마우스를 갖다댄후 오른쪽 클릭하면 그림 20과 같이 Add Library가 뜨며 그것을 눌러주면 됩니다.
.저희는 외부 라이브러리를 사용하는 것이이 External library를 선택해주시고, library file 경로 설정을 위해 그림 20 과 같이 버튼을 눌러줍니다.
그 다음 원하는 라이브러리의 .lib파일이 있는 곳에 들어가서 맨 끝에 d가 붙지 않은 파일하나를 눌러주면 완료됩니다.
그럼 .pro 파일에 lib 경로가 추가된 것을 볼 수 있는데요. 지금은 아래와 같이 하나의 lib만 추가된 것을 확인할 수 있습니다.
추가된 code를 보녕 win32(release), win32(debug), unix 총 세가지로 나눠서 library 가 추가된 것을 볼 수 있습니다. win32의 경우 window에서 동작하는 라이브러리의 경로를 지정한 것이며, unix의 경우 ubuntu에서 동작하는 라이브러리의 경로를 지정한 것입니다. 그리고 win32(release)와 win(debug)의 차이는 debug시 사용되는 라이브러리이냐 아니냐의 차이로 보시면 됩니다. 디버그시 사용되는 라이브러리의 끝에는 d가 붙은 것을 볼 수 있듯이 보통 저렇게 debug용에는 d를 붙혀서 제공됩니다. ( Ebus SDK는 아님)
그림 21의 경우 라이브러리를 하나만 추가한 것으로 나머지 라이브러리는 수동으로 하나하나 넣어줘야하는데요. 그건 매우 힘드니 아래 코드를 .pro에 넣어서 Opencv와 Ebus SDK의 lib과 bin 의 경로를 추가하도록 합시다.
# OpenCV lib && bin 경로 추가
win32:CONFIG(release, debug|release):{
LIBS += -L$$PWD/../opencv/build/x64/vc14/lib/ -lopencv_calib3d2413 -lopencv_contrib2413 -lopencv_core2413 -lopencv_features2d2413 -lopencv_flann2413 -lopencv_gpu2413 -lopencv_highgui2413 -lopencv_imgproc2413 -lopencv_legacy2413 -lopencv_ml2413 -lopencv_nonfree2413 -lopencv_objdetect2413 -lopencv_ocl2413 -lopencv_photo2413 -lopencv_stitching2413 -lopencv_superres2413 -lopencv_ts2413 -lopencv_video2413 -lopencv_videostab2413
LIBS += -L$$PWD/../opencv/build/x64/vc14/bin/ -lopencv_calib3d2413 -lopencv_contrib2413 -lopencv_core2413 -lopencv_features2d2413 -lopencv_flann2413 -lopencv_gpu2413 -lopencv_highgui2413 -lopencv_imgproc2413 -lopencv_legacy2413 -lopencv_ml2413 -lopencv_nonfree2413 -lopencv_objdetect2413 -lopencv_ocl2413 -lopencv_photo2413 -lopencv_stitching2413 -lopencv_superres2413 -lopencv_ts2413 -lopencv_video2413 -lopencv_videostab2413
LIBS += -L$$PWD/../opencv/build/x64/vc14/bin/opencv_core2413.dll
}
else:win32:CONFIG(debug, debug|release):{
LIBS += -L$$PWD/../opencv/build/x64/vc14/lib/ -lopencv_calib3d2413d -lopencv_contrib2413d -lopencv_core2413d -lopencv_features2d2413d -lopencv_flann2413d -lopencv_gpu2413d -lopencv_highgui2413d -lopencv_imgproc2413d -lopencv_legacy2413d -lopencv_ml2413d -lopencv_nonfree2413d -lopencv_objdetect2413d -lopencv_ocl2413d -lopencv_photo2413d -lopencv_stitching2413d -lopencv_superres2413d -lopencv_ts2413d -lopencv_video2413d -lopencv_videostab2413d
LIBS += -L$$PWD/../opencv/build/x64/vc14/bin/ -lopencv_calib3d2413d -lopencv_contrib2413d -lopencv_core2413d -lopencv_features2d2413d -lopencv_flann2413d -lopencv_gpu2413d -lopencv_highgui2413d -lopencv_imgproc2413d -lopencv_legacy2413d -lopencv_ml2413d -lopencv_nonfree2413d -lopencv_objdetect2413d -lopencv_ocl2413d -lopencv_photo2413d -lopencv_stitching2413d -lopencv_superres2413d -lopencv_ts2413d -lopencv_video2413d -lopencv_videostab2413d
LIBS += -L$$PWD/../opencv/build/x64/vc14/bin/opencv_core2413d.dll
}
else:unix: LIBS += -L$$PWD/../opencv/build/x64/vc14/lib/ -lopencv_calib3d2413
# Ebus SDK lib && bin 경로 추가
INCLUDEPATH += C:\Users\user3\Desktop\2022Grabber\eBUS_SDK\Includes
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../eBUS_SDK/Libraries/ -lEbTransportLayerLib64 -lEbUtilsLib64 -lPtConvertersLib64 -lPtUtilsLib64 -lPvAppUtils64 -lPvBase64 -lPvBuffer64 -lPvCameraBridge64 -lPvDevice64 -lPvDSSource64 -lPvGenICam64 -lPvGUI64_VC10 -lPvGUI64_VC11 -lPvGUI64_VC12 -lPvGUI64_VC14 –lPvPersistence64 -lPvSerial64 -lPvStream64 -lPvSystem64 -lPvTransmitter64 -lPvVirtualDevice64 -lSimpleImagingLib64
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../eBUS_SDK/Libraries/ -lEbTransportLayerLib64 -lEbUtilsLib64 -lPtConvertersLib64 -lPtUtilsLib64 -lPvAppUtils64 -lPvBase64 -lPvBuffer64 -lPvCameraBridge64 -lPvDevice64 -lPvDSSource64 -lPvGenICam64 -lPvGUI64_VC10 -lPvGUI64_VC11 -lPvGUI64_VC12 -lPvGUI64_VC14 –lPvPersistence64 -lPvSerial64 -lPvStream64 -lPvSystem64 -lPvTransmitter64 -lPvVirtualDevice64 -lSimpleImagingLib64
else:unix: LIBS += -L$$PWD/../eBUS_SDK/Libraries/ -lEbInstallerLib64
linux
INCLUDEPATH += \
-I/usr/include/opencv4/opencv2
LIBS += \
-L/usr/local/lib -lopencv_core -lopencv_calib3d -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_imgcodecs \
-lopencv_highgui -lopencv_ml -lopencv_shape -lopencv_photo -lopencv_objdetect -lopencv_stitching -lopencv_superres \
-lopencv_video -lopencv_videoio -lopencv_videostab -lopencv_imgproc
LIBS += \
-L/opt/pleora/ebus_sdk/linux-aarch64-arm/lib -lEbTransportLayerLib -lEbUtilsLib -lPtConvertersLib -lPtUtilsLib -lPvAppUtils \
-lPvBase -lPvBuffer -lPvCameraBridge -lPvDevice -lPvGUI -lPvGenICam -lPvPersistence -lPvSerial -lPvStream \
-lPvSystem -lPvTransmitter -lPvVirtualDevice -lSimpleImagingLib
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../../../opt/pleora/ebus_sdk/linux-aarch64-arm/lib/release/ -lEbTransportLayerLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../../../opt/pleora/ebus_sdk/linux-aarch64-arm/lib/debug/ -lEbTransportLayerLib
else:unix: LIBS += -L$$PWD/../../../../../opt/pleora/ebus_sdk/linux-aarch64-arm/lib/ -lEbTransportLayerLib
INCLUDEPATH += $$PWD/../../../../../opt/pleora/ebus_sdk/linux-aarch64-arm/include
DEPENDPATH += $$PWD/../../../../../opt/pleora/ebus_sdk/linux-aarch64-arm/include
사실 그림20~22의 과정 없이 위 코드만 .pro에 추가해주면 간단히 추가할 수 있습니다.
마지막으로 추가할 경로는 헤더파일의 경로로 헤더파일의 경로는 .pro에 “`INCLUDEPATH +=“` 로 추가해주기만 하면 됩니다. 이 경로는 아래 코드로 추가합니다.
# OpenCV 헤더파일 경로 추가
INCLUDEPATH += C:\Users\user3\Desktop\2022Grabber\opencv\build\include
# Ebus SDK 헤더파일 경로 추가
INCLUDEPATH += C:\Users\user3\Desktop\2022Grabber\eBUS_SDK\Includes
이 library가 정상적으로 추가됐는지 확인해 보는 방법은 그림 23과 같이 코드에 추가했을떄 빨간 줄이 뜨지 않는다면 정상적으로 연결된 것이고 그게 아니라면 다시 처음부터 해보는걸 권장합니ㅍ다. 그리고 프로젝트를 build 했을때 코드에 에러가 뜨지 않고 에러가 뜬다면 library 경로를 잘 연결했는지부터 의심해보길 권장합니다.
3. Ebus SDK
4. Grabber Code Review
이 섹션에서는 두개의 카메라를 연결하는 과정을 예시로 들어, 기존 Camera Grabber가 어떻게 작성되어있는지 설명할 것입니다. 이 섹션은 2번과 3번 섹션을 잘 알고 있다는 가정하에 작성되었음을 밝히며 만약 아직 자기만의 GUI를 제작해본 경험이 없거나 카메라 예제를 통해서 카메라를 한대라도 키는 것조차 하지 않은 상태라면 2번과 3번 섹션에 관한 공부를 더욱 하고 시작하는것을 권장합니다.
먼저 QT Designer를 이용해 제작한 Camera Grabber의 GUI는 그림 25와 같습니다. Qlabel을 이용해서 영상을 display 하며 총 5개의 버튼으로 조작하게 됩니다. ( 물론 사용하지 않는 버튼도 있음..예를 들어 Display 키키)
GUI는 총 네개의 버튼이 작동하며 각각이 mainwindow에서 중요하게 동작하는 대표 함수이기도 합니다. 각각의 버튼은 아래와 같은 역할을 합니다.
Initialize: (Ubuntu에서만 사용) 우분투에서는 네트워크 검색이 막혀있기 때문에 막혀있는 것을 풀어주기 위한 shell script를 실행시키고, 할당되어 있지 않은 카메라 IP를 CamInitialize 함수를 이용해 할당해줍니다.
Connect: Connect(const char* Mac) 함수를 사용해 Mac Address를 알고 있는 카메라와 연결하고, Thread를 start 해서 영상을 받기 시작합니다.
Record: Record thread를 실행시켜서 각 camera thread 부터 영상을 받아와서 bin 파일에 저장
Decode: .bin 파일에 저장된 영상을 .png 파일로 변환 후 저장
4.1 Mainwindow initialize
GUI가 시작될때 전역 변수들과 Thread 그리고 Slot 을 이용한 Signal을 설정해야합니다.
Camera Grabber 속 Thread는 그림 26과 같이 설계되어 있습니다. 카메라마다 Thread를 두며 record 전용 thread 도 사용합니다. 이렇게 총 세가지의 Thread를 초기화하며 전역변수 및 카메라 정보를 초기화한 코드는 다음과 같습니다.
C++ Example
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// bool
mDisplay=false;
mRecording=false;
mDecording=false;
// camera thread initialize
// thermal
mCamera[0] = new camthread(this,false,0);
mCamera[0]->mAcqusition = false;
// rgb
mCamera[1] = new camthread(this,true,1);
mCamera[1]->mAcqusition = false;
// Mac & IP
mMac[0] = "00:11:1c:03:57:1b";
mIp[0] = "192.168.0.3";
// Mac & IP
mMac[1] = "00:b0:9d:c9:b9:1c";
mIp[1] = "192.168.0.6";
qRegisterMetaType< cv::Mat >("cv::Mat");
// Save Thread Initialize
DThread=new savethread(this,mCamera[0],mCamera[1]);
// CamThread와 mainthread 연결
connect(mCamera[0], SIGNAL(Display(cv::Mat,int)), this, SLOT(SlotDisplay(cv::Mat,int)));
connect(mCamera[1], SIGNAL(Display(cv::Mat,int)), this, SLOT(SlotDisplay(cv::Mat,int)));
}
4.2 Init Button
- 함수명:
on_init_clicked()
– init 버튼을 눌렀을때 실행되며 카메라 연결과 관련된 설정값을 초기화 및 재설정 해주는 역할을 함 - 코드 설명:
ShellScript();
- ShellScript 함수를 실행해서 카메라 연결에 필요한 설정을 진행함 Xaiver 에서만 진행함
CamInitialize( mThermalMac.toStdString().c_str(), mThermalIp.toStdString().c_str() );
CamInitialize 함수를 실행해서 초기화 되어 있지 않은 카메라 IP와 Mac Address를 초기화 해줌
ShellScript()
- 사용 목적: 카메라 연결에 필요한 설정을 진행함 Xaiver 에서만 진행함
- 내부 함수: –
system("echo '서버 비밀번호' |" " sudo -S /opt/pleora/ebus_sdk/linux-aarch64-arm/bin/set_rp_filter.sh" " --mode=0 --restartnetworkstack=yes"))
: 값이 기본 1로 설정된 값을 0으로 변경하여, 통신을 위하여 network filtering 기능을 꺼둠system("echo '서버 비밀번호' | sudo -S /opt/pleora/ebus_sdk/linux-aarch64-arm/bin/set_socket_buffer_size.sh")
: 10485760 로 소켓 버퍼 사이즈 증가를 통해 데이터 받는 최대크기를 증가시킴system("echo '서버 비밀번호' | sudo -S /opt/pleora/ebus_sdk/linux-aarch64-arm/bin/set_socket_buffer_size.sh")
: eBUS 라이센스 활성화, 작동시 상시 활성화 해줘야함 필수 요소는 아님
CamInitialize(const char* Mac, const char* IpAdr)
- 사용 목적: 초기화 되어 있지 않은 카메라 IP와 Mac Address를 초기화 해줌
- 내부 함수:
–PvDeviceGEV* lDeviceSetIp = NULL;
: IP와 Mac Address 초기화하는 변수 지정
–PvResult lResult;
: 초기화 상태를 반환 받기 위한 변수 지정
–lResult = lDeviceSetIp->SetIPConfiguration( Mac, IpAdr, "255.255.0.0");
: 함수 인자로 받은 Mac Address의 IP를 재설정
–lResult.GetCodeString().GetAscii()
: 초기화가 잘못 됐을 경우 값 원인을 반환
C++ Example
void MainWindow::on_m_init_clicked()
{
//Run Shell Script ( Ubuntu 에서만 사용)
ShellScript();
//Camera Ip congigure
CamInitialize( mMac[0].toStdString().c_str(), mIp[0].toStdString().c_str() );
CamInitialize( mMac[1].toStdString().c_str(), mIp[1].toStdString().c_str() );
}
void MainWindow::ShellScript()
{
if (system("echo 'v1s10nlab2019' |"
" sudo -S /opt/pleora/ebus_sdk/linux-aarch64-arm/bin/set_rp_filter.sh"
" --mode=0 --restartnetworkstack=yes"))
{
cout << "set_rp_filter failed" << endl;
}
if (system("echo 'v1s10nlab2019' | sudo -S /opt/pleora/ebus_sdk/linux-aarch64-arm/bin/set_socket_buffer_size.sh"))
{
cout << "set_soket_buffer failed" << endl;
}
else cout << "set_soket_buffer" << endl;
if (system("echo 'v1s10nlab2019' | sudo -S /opt/pleora/ebus_sdk/linux-aarch64-arm/bin/set_usbfs_memory_size.sh"))
{
cout << "set_usbfs_memory_size failed" << endl;
}
else cout << "set_usbfs_memory_size" << endl;
system("echo 'v1s10nlab2019' | sudo -S service eBUSd stop");
system("echo 'v1s10nlab2019' | sudo -S service eBUSd start");
}
void MainWindow::CamInitialize(const char* Mac, const char* IpAdr)
{
PvDeviceGEV* lDeviceSetIp = NULL;
PvResult lResult;
lResult = lDeviceSetIp->SetIPConfiguration( Mac, IpAdr, "255.255.0.0");
if (!lResult.IsOK()) cout << lResult.GetCodeString().GetAscii() << endl;
}
이 이후는 이 About Grabber(3)에 계속 업데이트해서 완료하도록 하겠습니다.
4.2 Connect Button
4.3 Record Button
4.4 Decode Button
음… 혹시 그림26과 같이 멀티쓰레드로 구성하는 이유는 1개의 쓰레드에서 2개의 카메라 데이터를 처리하면 temporal alignment가 맞지 않는 이유뿐인가요?
쓰레드를 1개로 구성하고도 temporal alignment를 동기화하는 방법은 없을지 궁금하여 질문드립니다.
일단 기존 QT로 작성된 코드와 달리 저렇게 multi thread로 구성한 이유는 하나입니다. 예전에 MFC로 작성했던 코드가 저렇게 Multi thread로 구성되었고 그당시에 하나의 thread 안에서 처리하면 무조건적으로 동기화가 맞지않았던 기억이 있어서 QT에서도 동일하게 Multi thread로 구성했습니다.
사실 제가 동기화 방법에 대해 따로 서베이하면서 공부한게 아니라 어떤 방법이 있을지는 모르겠습니다.