차근차근/OpenCV

OpenCV 편하게 사용하기 (팁)

예쁜꽃이피었으면 2014. 7. 30. 09:58

http://darkpgmr.tistory.com/m/post/36

 

1. OpenCV 링크 편하게 하기

2. OpenCV 행렬 원소접근 편하게 하기

3. TypedMat 사용법

 

 

 

1. OpenCV 링크 편하게 하기

 

OpenCV를 이용한 프로그램을 작성하려면 필요한 헤더화일 및 라이브러리 파일들을 링크시키기 위해 이런 저런 세팅을 해 주어야 합니다.

 

저는 OpenCV 헤더파일 및 라이브러리 파일들을 다음과 같이 하나의 파일에 모두 넣어놓고 필요한 모듈만 주석을 제거하여 사용합니다 (물론 프로젝트 설정에서 opencv include directory, opencv library directory 는 별도로 설정해 주어야 합니다).

 

이제 opencv를 사용하고 싶으면 아래 파일만 include하면 ok입니다.

 

<use_opencv.h>

#pragma once

 

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc.hpp"

//#include "opencv2/core/core.hpp"

//#include "opencv2/core/core_c.h"

//#include "opencv2/highgui/highgui_c.h"

//#include "opencv2/imgproc/imgproc_c.h"

//#include "opencv2/video/video.hpp"

//#include "opencv2/nonfree/nonfree.hpp"

//#include "opencv2/videostab/videostab.hpp"

//#include "opencv2/features2d/features2d.hpp"

//#include "opencv2/objdetect/objdetect.hpp"

//#include "opencv2/flann/miniflann.hpp"

//#include "opencv2/photo/photo.hpp"

//#include "opencv2/calib3d/calib3d.hpp"

//#include "opencv2/ml/ml.hpp"

//#include "opencv2/contrib/contrib.hpp"

//#include "opencv2/ts/ts.hpp"

//#include "opencv2/stitching/stitcher.hpp"

//#include "opencv2/legacy/legacy.hpp"

 

#ifdef _DEBUG

        #pragma comment(lib,"opencv_core241d.lib")

        #pragma comment(lib,"opencv_highgui241d.lib")

        #pragma comment(lib,"opencv_imgproc241d.lib")

//      #pragma comment(lib,"opencv_video241d.lib")

//      #pragma comment(lib,"opencv_nonfree241d.lib")

//      #pragma comment(lib,"opencv_videostab241d.lib")

//      #pragma comment(lib,"opencv_features2d241d.lib")

//      #pragma comment(lib,"opencv_objdetect241d.lib")

//      #pragma comment(lib,"opencv_flann241d.lib")

//      #pragma comment(lib,"opencv_photo241d.lib")

//      #pragma comment(lib,"opencv_calib3d241d.lib")

//      #pragma comment(lib,"opencv_ml241d.lib")

//      #pragma comment(lib,"opencv_contrib241d.lib")

//      #pragma comment(lib,"opencv_ts241d.lib")

//      #pragma comment(lib,"opencv_stitching241d.lib")

//      #pragma comment(lib,"opencv_legacy241d.lib")

#else

        #pragma comment(lib,"opencv_core241.lib")

        #pragma comment(lib,"opencv_highgui241.lib")

        #pragma comment(lib,"opencv_imgproc241.lib")

//      #pragma comment(lib,"opencv_video241.lib")

//      #pragma comment(lib,"opencv_nonfree241.lib")

//      #pragma comment(lib,"opencv_videostab241.lib")

//      #pragma comment(lib,"opencv_features2d241.lib")

//      #pragma comment(lib,"opencv_objdetect241.lib")

//      #pragma comment(lib,"opencv_flann241.lib")

//      #pragma comment(lib,"opencv_photo241.lib")

//      #pragma comment(lib,"opencv_calib3d241.lib")

//      #pragma comment(lib,"opencv_ml241.lib")

//      #pragma comment(lib,"opencv_contrib241.lib")

//      #pragma comment(lib,"opencv_ts241.lib")

//      #pragma comment(lib,"opencv_stitching241.lib")

//      #pragma comment(lib,"opencv_legacy241.lib")

#endif

 

use_opencv.h

 

 

2. OpenCV 행렬 원소접근 편하게 하기

 

저는 opencv를 사용하면서 가장 불편한 점 중의 하나가 행렬(Mat)의 원소를 접근하는 것입니다. 특히나 영상처리를 하다보면 이미지 픽셀 단위로 처리를 할 필요가 있는데 OpenCV가 제공하는 원소 접근 방법(at)은 상당히 불편합니다.

 

그래서 아래와 같이 Wrapper class를 하나 작성해 보았습니다.

 

template<class T>

class TypedMat

{

        T** m_pData;

        int m_nChannels;

        int m_nRows, m_nCols;

 

public:

        TypedMat():m_pData(NULL),m_nChannels(1),m_nRows(0),m_nCols(0){}

        ~TypedMat(){if(m_pData) delete [] m_pData;}

 

        // OpenCV Mat 연동 (메모리 공유)

        void Attach(const cv::Mat& m);

        void Attach(const IplImage& m);

        TypedMat(const cv::Mat& m):m_pData(NULL),m_nChannels(1),m_nRows(0),m_nCols(0) { Attach(m);}

        TypedMat(const IplImage& m):m_pData(NULL),m_nChannels(1),m_nRows(0),m_nCols(0) { Attach(m);}

        const TypedMat & operator =(const cv::Mat& m){ Attach(m); return *this;}

        const TypedMat & operator =(const IplImage& m){ Attach(m); return *this;}

 

        // 행(row) 반환

        T* GetPtr(int r)

        { assert(r>=0 && r<m_nRows); return m_pData[r];}

 

        // 연산자 중첩 (원소접근) -- 2D

        T * operator [](int r)

        { assert(r>=0 && r<m_nRows); return m_pData[r];}

 

        const T * operator [](int r) const

        { assert(r>=0 && r<m_nRows); return m_pData[r];}

 

        // 연산자 중첩 (원소접근) -- 3D

        T & operator ()(int r, int c, int k)

        { assert(r>=0 && r<m_nRows && c>=0 && c<m_nCols && k>=0 && k<m_nChannels); return m_pData[r][c*m_nChannels+k];}

 

        const T operator ()(int r, int c, int k) const

        { assert(r>=0 && r<m_nRows && c>=0 && c<m_nCols && k>=0 && k<m_nChannels); return m_pData[r][c*m_nChannels+k];}

};

 

template<class T>

void TypedMat<T>::Attach(const cv::Mat& m)

{

        assert(sizeof(T)==m.elemSize1());

 

        m_nChannels = m.channels();

        m_nRows = m.rows;

        m_nCols = m.cols;

        

        if(m_pData) delete [] m_pData;

        m_pData = new T * [m_nRows];

        for(int r=0; r<m_nRows; r++)

        {

                m_pData[r] = (T *)(m.data + r*m.step);

        }

}

 

template<class T>

void TypedMat<T>::Attach(const IplImage& m)

{

        assert(sizeof(T)==m.elemSize1());

 

        m_nChannels = m.nChannels;

        m_nRows = m.height;

        m_nCols = m.width;

        

        if(m_pData) delete [] m_pData;

        m_pData = new T * [m_nRows];

        for(int r=0; r<m_nRows; r++)

        {

                m_pData[r] = (T *)(m.imageData + r*m.widthStep);

        }

}


 

use_opencv.h

 

 

3. TypedMat 사용법

 

메모리를 공유하기 때문에 추가적인 연산 로드는 거의 없습니다. IplImage, cv::Mat을 지원합니다. 사용법은 다음과 같습니다.

 

* 이미지의 경우

#include "use_opencv.h"

 

Mat image;

 

TypedMat<unsigned char> tm = image;    // 연결방법 1

TypedMat<unsigned char> tm; tm = image;    // 연결방법 2

TypedMat<unsigned char> tm; tm.Attach(image);    // 연결방법 3

 

// image가 1채널 grayscale 이미지일 경우

tm[y][x] = 100;    // (x,y)의 픽셀값을 100으로 설정

 

// image가 3채널 color 이미지일 경우

tm(y,x,0) = 100;    // (x,y)의 픽셀의 blue값을 100으로 설정

tm(y,x,1) = 200;    // (x,y)의 픽셀의 green값을 200으로 설정

tm(y,x,2) = 50;    // (x,y)의 픽셀의 red값을 50으로 설정

 

* 2D float 타입 행렬의 경우

 

#include "use_opencv.h"

Mat f_image;

TypedMat<float> fm = f_image;

fm[y][x] = 3.12f;

반응형