반응형

사용하는 제품은 FLIR사의 "BFS-U3-51S5C-C" 제품이다.

 

해당 제품을 통해 얻어지는 영상을 Visual Studio에서 OpenCV를 통해 C++로 처리하고자 한다.

 

www.flirkorea.com/support-center/iis/machine-vision/downloads/spinnaker-sdk-and-firmware-download/  

 

Spinnaker SDK 다운로드

Spinnaker SDK를 다운로드하세요.

www.flirkorea.com

 

우선 위의 링크를 통해 Spinnaker SDK를 설치해준다.

 

 

저장소에 보면 위와 같이 Windows 환경에서 SpinnakerSDK의 Full 버전을 다운받을 수 있도록 제공해주고 있다.

 

 

 

그리고 설치를 진행하는 중 위와 같은 과정을 진행하게 되는데 위의 "Camera Evaluation"의 경우 카메라의 정상작동 여부만을 확인할 수 있도록 Viewer 와 이와 관련된 간단한 프로그램들만 설치되는 과정으로 보이고 코드작업을 통해 디테일한 작업을 진행하고자 한다면 아래의 "Application Development"를 선택해야 하는 것으로 보인다.

 

 

그리고 설치가 완료되면

"C:/Program Files/ FLIR Systems/ Spinnaker/ src/ " 의 경로에서 샘플 코드들을 확인할 수 있다.

 

 

나는 현재 Visual 2019 버전을 사용중인데 해당 버전은 아직 지원되지 않는 것 같다.

그래서 MS 홈페이지에서 VisualStudio2015를 설치를 진행하려 했으나

위와 같은 창에서 패키지가 없거나 찾을 수 없다는 내용만 뜨면서 진행이 되지 않는 문제가 발생하였다.

 

결국 iso 형식의 visual2015를 구해 진행하니 설치가 잘 되었다.

그리고 앞에서 받은 Sample Code들을 돌려봐도 잘 실행되는 것을 확인할 수 있었다.

 

그럼 이제 OpenCV를 연동하여 본격적으로 작업에 들어가보자.

 

우선 OpenCV는 3.2 버전을 다운받아 설치해주었다.

 

이 과정에서는 아래 블로그를 참고하여 진행하였다.

 

www.cnblogs.com/dinghongkai/p/11631147.html

 

VS 2017 + OpenCV + Spinnaker SDK(PointGrey) 配置 - Hongkai_Ding - 博客园

1. OpenCV 配置 1.1 下载 opencv 源码,并将其添加至环境变量 D:\opencv4.1\build\x64\vc15\bin 注:vs2015 选 vc14,vs2017 选 vc

www.cnblogs.com

 

우선 프로젝트 상단의 x86을 x64로 변경해준다.

 

그리고 프로젝트 설정에서 추가포함드렉터리와 추가라이브러리디렉토리를 추가해주고

링커->입력 부분에서 opencv_world320d.lib을 추가해준다.

 

여기까지 됐으면 프로젝트를 다시한번 빌드하여 오류가 없는지 확인해보자.

 

그럼 이제 윈도우 환경변수를 추가해주자.

 

 

 

 

 

위의 설정이 완료되었으면 다시 코드로 돌아와 아래 내용을 추가해보자.

 

 

그리고 이상이 없다면 프로젝트 설정이 끝난 것이고 이제 FLIR카메라에서 얻어진 영상을

OpenCV로 처리할 수 있을 것이다.

반응형
반응형

 

OV7670 카메라 모듈의 핀은 위와 같이 나타나 있다.

 

SCL과 SDA는 SCCB 통신을 위한 핀으로

SCL은 input Port, SCCB 인터페이스 제어 클럭을 입력받는 핀이고

SDA는 InOut Port로 통신을 위한 데이터를 전송하고 전송받는 핀이다.

 

 

MCLK는 시스템 클럭으로 Input Port이고 여기에 입력되는 클럭을 통해 이미지 데이터를

D0~D7로 출력하고 픽셀클럭(PCLK)를 출력하게 된다.

 

 

 

 

위 이미지는 OV7670 카메라 모듈의 Functional Block Diagram(FBD) 이다.  XCLK핀에 클럭 신호를 입력해주면

이를 기반으로 Video Timing Generator에서 VSYNC, HSYNC, PCLK 신호를 출력해준다.

 

 

그럼 우선 SBBC 통신을 통해 데이터를 받아오기 위한 설정부터 진행해보자.

일단 왜 SBBC 통신을 쓰는지, SBBC통신의 장점을 간단히 적자면

SBBC통신(I2C통신)은 시리얼통신과 다르게 동기화 통신방식을 사용하여 통신속도를 따로 정해주지 않아도 되고

클럭신호를 통해 데이터의 전송  타이밍을 맞추게 된다.

(그리고 많은 센서를 동시에 편하게 연결할 수 있다고 한다.)

 

 

위의 그림은 I2C 통신을 나타내는 그림으로 다음 두 그림을 참고하여 설명하겠다.

 

 

 

SDA신호와 SCL신호는 모두 풀업저항에 의해 초기에 HIGH상태를 유지한다.

 

그리고 SDA신호가 LOW로 떨어지게 되면 데이터 전송을 시작하게 되고 그 이후 클럭신호(SCL)에 맞춰

데이터 전송이 진행된다.

 

Device Address의 데이터 전송이 끝났으면 Read/Write 데이터를 전송하고 쓰기모드일 경우

데이터가 잘 전송되었는지는 Slave측의 ACK 신호를 통해 확인하게 된다. 

 

그리고 난 후 SCL이 LOW신호일 때 다음 데이터인 Register Address 데이터 전송을 위해 data값을 바꾸고 위의 내용들을 반복하여 진행하게 된다.

 

 

 

위의 그림에서 SDA신호가 0이 되면 통신 시작

-> 그 다음 SCL이 0이 되는 순간부터 데이터 전송

-> 8개 비트 데이터(7bit Address, 1bit R/W) 전송

-> ACK확인

-> 그 다음 데이터 전송

-> ...

 

을 진행하게 된다.

 

위는 PCF8574A 라는 장치의 Address에 A0앞에 R/W의 정보가 담기는 것을 확인할 수 있다.

 

즉 Address 안에 R/W 정보를 담고 있는 것이다.

 

 

OV7670.pdf
0.84MB

 

 

 

위 파일은 OV7670의 메뉴얼 파일이다.

 

 

메뉴얼을 보면 위와 같이 Register을 설정해주는 부분이 보이는데 이 부분에 대한 설정 값들을 SBBC 통신을 통해

진행하게 된다. 즉 위의 설정값을 통해 어떠한 데이터를 받아올 것인지 설정해주게 된다.

 

 

OV7670_config_rom.v
0.00MB

 

 

 

위 파일이 Register에 대한 값들을 설정해주기 위한 값들을 담고있다.

 

 

위의 addr값이 0 일때의 조건문을 보면

dout 값에 16'h1280 의 값을 넣어주는 것을 확인할 수 있다.

 

이는 Register의 12번 주소에 0x80 이라는 값으로 설정해주겠다는 의미이다.

 

SCCB.zip
0.01MB

 

 

위의 파일은 SCCB 통신을 위한 코드가 담긴 파일이다.

 

Camera_configure 모듈을 살펴보면 입력으로

CLK, start, RST가 존재하고 출력신호로 SIOC, SIOD, done 신호가 존재한다.

 

내부적으로는 config 모듈과 SCCB_Interface 모듈, ROM 모듈이 존재하며

이들과의 관계를 통해 결과적으로 SIOC, SIOD 출력을 내보내게 되고

이를 통해 카메라모듈과 통신을 진행하게 된다.

 

start신호는 임의로 만들어주었다.

 

ZedBoard에서 출력되는 신호는 100MHz의 클럭이 출력되므로

아래와 같이 clock_divider 이라는 모듈을 만들어 100MHz 신호를 1MHz로 바꿔주어 출력하고 이를 Configure 모듈로 입력하여 통신을 진행하도록 한다.

 

또한 start신호는

 

위와 같이 cnt가 200보다 작을때는 계속 증가시키고

200이 되는 순간 start를 1로, 201이 되면 다시 start를 0으로 하고 cnt가 증가하지 않도록 함으로서

순간적인 start신호를 만들어 주었다.

 

clock_divider.v
0.00MB

 

 

 

 

그리고 난 후 이를 minized 보드에 입히고

실행시키면 Camera Module에서 pixel clock과 함께 데이터 신호들이 나오고 있는 것을

오실로스코프를 통해 확인할 수 있다.

 

 

 

 

위의 D0신호는 카메라 모듈의 Vsync, D1은 HSync,

D2~D5는 Image Data를 의미한다.

 

확인해보면 조금 이상하긴 하지만 HSync가 멈추는 사이사이 Vsync가 1이 되면서 프레임완료 신호를 출력하는 것을

확인할 수 있다.

 

 

그리고 Href 가 High인 상태에서 각각의 데이터 신호들이 전달되는 것을 확인할 수 있다.

 

 

그럼 XCLK로 몇 Hz의 신호를 주어야 할까?

 

Hacking the OV7670 camera module (SCCB cheat sheet inside)

An in-depth look of the OV7670 camera module The OV7670 is a low cost image sensor + DSP that can operate at a maximum of 30 fps and 640...

embeddedprogrammer.blogspot.com

위의 블로그를 참고하면 30fps의 경우 24MHz의 클럭을 입력하여야 한다고 한다.

 

 

*******************************************************************

하지만 통신이 완료되면 done신호가 1이 되어 출력되어야 할 것 같은데 이는 아직 출력되지 않고 있다.

 

이를 확인해볼 필요가 있다.

 

반응형
반응형

●  히스토그램 작성 순서도

●  cvCreateHist 함수  (히스토그램을 정의하는데 사용하는 함수)

 

CvHistogram* cvCreateHist( int dims, int *sizes, int type, 

                                                     float **range=NULL, int uniform=1)

 

 

-> dims

   히스토그램의 차원을 지정.

   흑백 영상이면 1, 컬러 영상이면 3차원.

 

-> sizes

    히스토그램 차원의 크기를 나타내며 배열로 표시함. 

    1차원 256 흑백영상의 경우 0부터 255까지 256개의 박대를 사용하므로

         int sizes[1] = {256}  으로 나타낼 수 있다.

    3차원 컬러영상의 경우 각각의 태널은 256개의 막대를 사용하므로

         int sizes[3] = {256, 256, 256}  으로 나타낼 수 있다.

 

-> type

    히스토그램 표현 형식을 나타낸다.

    type = CV_HIST_ARRAY이면 다채널 밀집 배열 (0인 원소가 적은 배열)을 나타내고

    type = CV_HIST_SPARSE이면 다채널 희소 배열 (0인 원소가 많은 배열)을 나타낸다.

 

-> ranges

    히스토그램의 x축 범위를 나타낸다.

 

-> uniform

    히스토그램에서 막대 사이의 간격을 일정하게 할 것인지 결정한다.

    uniform ≠ 0 이면 막대의 간격을 일정한 간격으로 한다.

 

 

●  cvCalcHist 함수 (영상으로부터 히스토그램을 계산하는데 사용하는 함수)

 

void cvCalcHist( IplImage** img, CvHistogram* hist);

 

 

->  img

     원 영상을 나타냄

 

->  hist

     히스토그램에 대한 포인터를 나타낸다.

 

 

●  cvGetMinMaxHistValue 함수 (막대에 대한 최대 빈도수와 최소 빈도수를 구함)

 

void cvGetMinMaxHistValue( CvHistogram* hist,

                                                 float* value_min, float* value_max);

 

 

->  hist

     히스토그램을 나타냄

 

->  value_min

     히스토그램의 최소 빈도수를 나타낸다.

 

->  value_max

     히스토그램의 최대 빈도수를 나타낸다.

 

 

●  cvScale 함수 (하나의 배열을 다른 배열로 선형 변환헤 의해 변환하는 함수)

 

void cvScale( CvArr* src, CvArr* dst, double scale=1, double shift=0);

 

 

->  src

      원 영상을 나타낸다.

 

->  dst

      목적 영상을 나타낸다.

 

->  scale

      스케일 파라미터를 나타낸다.

 

->  shift

      이동 파라미터를 나타낸다.

 

         cvScale() 함수는 dst = src * scale + shift 에 의해 변환된다.(cvConvertScale()와 동일)

 

 

●  cvRectangle 함수  (직사각형을 그리기 위한 함수)

 

void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1 );

 

 

->  img

     직사각형이 그려질 영상을 나타냄

 

->  pt1

     직사각형의 모서리를 나타낸다.

 

->  pt2

     직사각형의 반대편 모서리를 나타낸다.

 

->  color

     직사각형의 선의 색상을 나타낸다.

 

->  thickness

     직사각형의 선의 두께를 나타낸다.

 

          cvRectangle() 함수에서 모서리 좌표 pt1과 pt2를 정할 때 원정이 어디에 위치하느냐는 중요한 문제이다.

          영상 좌표에서 원점은 왼쪽 상단임을 알고있자!

 

 

●  cvGetReal1D 함수  (1차원 히스토그램에서 i번째 막대의 빈고수를 얻기 위한 함수)

 

double cvGetReal1D( CvArr* arr, int idx0 );

 

 

-> arr

     1차원 배열을 나타낸다.

 

->  idx0

     원소의 위치에 대한 인덱스를 나타낸다.

     cvGetReal1D(histo->bins, i) 는 배열 bins 에서 i번째 인덱스에 대한 원소를 반환한다.

 

 

 

●  cvSet 함수  (영상을 주어진 값으로 설정할 때 사용)

 

void cvSet( CvArr* arr, CvScalar valuem CvArr* mask=0 );

 

 

->  arr

     원 영상을 나타낸다.

 

->  value

     채울 값을 지정한다.

 

->  mask

     마스크를 나타낸다.

 

         cvSet(histImage, cvScalarAll(255), 0) 이면 영상 histImage의 픽셀값을 255로 설정한다.

 

         cvScalarAll(double num);

               ->  모든 스칼라의 value들을 num 으로 초기화시켜준다.

 

 

 

●  cvEqualizeHist 함수  (흑백 영상에서 히스토그램 평활화하는데 사용하는 함수)

 

void cvEqualizeHist(CvArr* src, CvArr* dst);

 

 

->  src

     흑백 영상을 나타낸다.

 

->  dst

     목적 영상을 나타낸다.

 

 

 

출처: OpenCV를 이용한 영상처리( 임동훈 지음)


    

반응형

'OpenCV > Histogram' 카테고리의 다른 글

히스토그램  (0) 2020.12.29
히스토그램 예제  (0) 2019.08.12
반응형

Disparity Map을 생성하기 위해 한 쌍의 스테레오 이미지를 불러와 연산을 수행하여야 한다.

해당 스테레오 이미지는 아래의 링크를 통해 다운받았고 혹시 모르니 첨부해놓도록 하겠다.

 

 

 

https://vision.middlebury.edu/stereo/data/scenes2003/

 

2003 Stereo Datasets

2003 Stereo datasets with ground truth These datasets were created by Daniel Scharstein, Alexander Vandenberg-Rodes, and Rick Szeliski. They consist of high-resolution stereo sequences with complex geometry and pixel-accurate ground-truth disparity data. T

vision.middlebury.edu

left.bmp.bmp
0.48MB
right.bmp.bmp
0.48MB

 

 

 

 

 

 

 

Verilog HDL을 통해 이미지파일을 불러오고 Disparity값을 구하여 Depth Map을 생성한 후 결과 파일을 저장하는

과정을 진행하도록 하겠다.

 

 

우선 Verilog에서는 이미지파일을 그대로 가져와 연산을 수행하기 힘들기에

Matlab을 통해 .hex파일로 변환해준 후 작업을 진행해야 한다.

 

 

Matlab 코드는 위와 같다.

 

imread를 통해 bmp파일을 불러와 b에 저장하고 해당 값들은 a에 저장된 후

작성되게 된다.

 

이 과정에서 반복횟수은 375와 450은 각각 이미지파일의 Width와 Height를 의미한다.

 

위의 과정을 통해 left이미지와 right이미지 파일을 각각 left.hex, right.hex 파일로 변환해주도록 한다.

 

해당 이미지파일은 Image Rectification과정이 수행된 완전한 수평관계의 이미지들이므로 Rectification과정은 따로

수행하지 않아도 된다.

 

정확한 3차원 Depth Data를 추출하기 위해선 카메라의 초점거리와 두 카메라 사이의 간격을 알아야 정확한 거리를

계산할 수 있지만 이미지 파일만을 통해선 이러한 스펙들을 알아내기 힘들기에 초점거리와 영상 사이의 거리는 임의로 지정하고 따라서 Depth정보는 정확한 거리가 아닌 상대적인 거리임을 알아두도록 하자.

 

 

진행 순서는 아래와 같다.

 

 

1. ImageFile을 불러와 Gray_Scale의 데이터로 표현

  

   이 과정에서 1열의 Image File Data를 2차원 배열 크기로 지정해줌으로서 나중에 계산하기 용이하도록 한다.

 

 

2. 기준점 지정

 

    이 과정에서는 기준이 되는 좌측 이미지의 어떠한 점(pixel)에 대하여 계산을 진행할 것인지를 지정하게 된다.

    입력으로는 CLK신호화 En신호를 두어 En신호가 High상태라면 CLK에 맞추어 Row, Column의 좌표를 출력하고

    En신호가 다시 Low를 갖도록 한다.

 

 

3. 기준영상의 기준점과 주변 데이터를 1열의 형태로 출력

 

    2단계에서 지점을 정하였으면 해당 지점 주변의 데이터를 출력하도록 한다. 나는 9x9 크기의 윈도우를 생성하여

    진행할 것이므로 총 81개의 데이터를 1열로 표현하여 출력하도록 한다.

 

 

4. 기준영상의 데이터를 토대로 우측이미지 탐색

 

    앞에서 좌측 이미지의 데이터를 받아온 위치를 알고 있고 Stereo Image는 Rectification이 진행되었으므로 해당 Row

    만을 탐색하면 된다. 따라서 우측 이미지의 왼쪽 끝부터 오른쪽 끝까지 해당 Row의 9x9 Window를 생성하고 입력받

    은 기준 영상의 데이터와 가장 유사한 점을 선택, 좌측 기준점과 우측 탐색점과의 Disparity값을 출력하도록 한다.

 

5.  출력된 Disparity값을 통해 거리정보를 계산하고 다시 2단계로 돌아가 그 다음 지점의 기준점에 대해 위의 내용을

    반복한다.

반응형

'FPGA > Verilog 공부' 카테고리의 다른 글

VIVADO 사용법(완전 기초)  (2) 2020.12.29
Verilog를 통한 MUX회로 구현  (0) 2020.12.29
OV7670 카메라 영상 출력  (0) 2020.07.28
Verilog를 이용한 Pulse 출력 확인  (0) 2020.07.19
BRAM  (0) 2020.07.08
반응형

https://webnautes.tistory.com/1030

 

Ubuntu 16.04에 opencv_contrib 포함하여 OpenCV 4.0.1 설치하는 방법

OpenCV 4.0.1과 opencv_contrib(extra modules)를 컴파일하여 Ubuntu 16.04에 설치하는 방법을 다룹니다. ps. Ubuntu 18.04에 OpenCV를 설치하는 방법은 다음 포스트를 참고하세요 [OpenCV/Ubuntu 개발 환경] - Ub..

webnautes.tistory.com

https://agiantmind.tistory.com/183

 

[Ubuntu] Ubuntu 16.04 + OpenCV 3.2 설치

※ 시스템 환경 - Ubuntu 16.04.2 LTS 64bit - OpenCV 3.2 - 설치일: 2017.06.12 ※ 참고자료 1. 멈춤보단 천천히라도 - Ubuntu 16.04에 opencv_contrib 포함하여 OpenCV 3.2 설치 위 블로그에 OpenCV 설치에 대한..

agiantmind.tistory.com

 

위의 두 블로그 글을 참고하였다.

 

우선 설치된 OpenCV가 있다면 새로 설치하는 과정에서 오류가 발생할 수 있으므로 기존의 OpenCV를 제거해준다.

 

$ pkg-config --modversion opencv

 

를 통해 기존의 openCV가 설치되어있는지 확인한다.

설치되어 있을 경우

위와 같이 설치된 OpenCV의 버전이 출력되게 되고

 

설치되어있지 않을 경우

 

위와 같은 내용이 출력되게 된다.

 

설치된 경우

$ sudo apt-get purge libope cv* python-opencv

$ sudo apt-get autoremove

 

과정을 통해 삭제하고 진행하도록 한다.

(설치되어있지 않은 경우 바로 진행하도록 한다.)

 

2. 기존 설치된 패키지 업그레이드

 

기존에 설치된 패키지들의 새로운 버전이 저장소에 있다면 리스트를 업데이트 하기 위해 실행한다.

또한 업그레이드를 진행하도록 한다.

 

$ sudo apt-get update

$ sudo apt-get upgrade

 

3. OpenCV 컴파일 전 필요한 패키지 설치

 

OpenCV를 컴파일하는데 사용하는 것들이 포함된 패키지들을 설치한다.

 

$ sudo apt-get install build-essential cmake

$ sudo apt-get install pkg-config

$ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev

$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libxvidcore-dev libx264-dev libxine2-dev

$ sudo apt-get install libv4l-dev v4l-utils

$ sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

$ sudo apt-get install libqt4-dev

$ sudo apt-get install mesa-utils libgl1-mesa-dri libqt4-opengl.dev

$ sudo apt-get install libatlas-base-dev gfortran libeigen3-dev

$ sudo apt-get install python2.7-dev python3-dev python-numpy python3-numpy

 

(각 코드에 대한 자세한 내용은 위의 블로그에 자세히 설명되어있다)

 

4. OpenCV 설정과 컴파일 및 설치

 

소스코드를 저장할 임시 디렉토리를 생성하여 이동한다.

$ mkdir opencv

$ cd opencv

 

OpenCV 3.2.0 소스코드를 다운로드 받아 압축을 풀어준다.

 

$ wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.2.0.zip 

불러오는 중입니다...

$ unzip opencv.zip

$ wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.2.0.zip 

불러오는 중입니다...

$ unzip opencv_contrib.zip

 

 

3.2) OpenCV 빌드

 

$ cd opencv-3.2.0/

$ mkdir build

$ cd build

 

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=OFF -D WITH_IPP=OFF -D WITH_1394=OFF -D BUILD_WITH_DEBUG_INFO=OFF -D BUILD_DOCS=OFF -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D ENABLE_NEON=ON -D WITH_QT=ON -D WITH_OPENGL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.2.0/modules -D WITH_V4L=ON -D WITH_FFMPEG=ON -D WITH_XINE=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D PYTHON_INCLUDE_DIR=/usr/include/python2.7 -D PYTHON_INCLUDE_DIR2=/usr/include/x86_64-linux-gnu/python2.7 -D PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so ../

 

컴파일을 시작하기 전에 사용중인 컴퓨터의 CPU 코어수를 확인한다.

 

$ cat /proc/cpuinfo | grep processor | wc -l(알파벳 i가 아닌 l)

$ time make -j4(여기서 4는 코어수)

$ sudo make install

 

4. 설치확인

 

$ pkg-config --modversion opencv

$ pkg-config --libs --cflags opencv

 

 

 

5. 예제코드 실행

 

opencv디렉토리에

$ gedit Test.cpp

 

를 통해 코드를 입력한다.

 

 

#include <opencv/hughgui.h>

int main()
{
	IplImage *image = cvLoadImage("lena.jpeg");
    cvShowImage("Test", image);
    cvWaitKey(0);
    cvReleaseImage(&image);
}

 

 

 

 

$ g++ -o imgvoew Test.cpp $(pkg-config --libs --cflags opencv)

 

$ ./imgview

 

반응형

+ Recent posts