검색결과 리스트
글
OpenCV 편하게 사용하기 (팁)
1. OpenCV 링크 편하게 하기
2. OpenCV 행렬 원소접근 편하게 하기
3. TypedMat 사용법
1. OpenCV 링크 편하게 하기
OpenCV를 이용한 프로그램을 작성하려면 필요한 헤더화일 및 라이브러리 파일들을 링크시키기 위해 이런 저런 세팅을 해 주어야 합니다.
저는 OpenCV 헤더파일 및 라이브러리 파일들을 다음과 같이 하나의 파일에 모두 넣어놓고 사용합니다 (물론 프로젝트 설정에서 opencv include directory, opencv library directory 는 별도로 설정해 주어야 합니다).
이제 opencv를 사용하고 싶으면 아래 파일만 include하면 ok입니다.
<use_opencv.h>
#ifndef __USE_OPENCV_H__
#define __USE_OPENCV_H__
#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 // _DEBUG
#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.widthStep/(m.width*m.nChannels));
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);
}
}
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;
by 다크 프로그래머
'프로그래밍 > opencv' 카테고리의 다른 글
OpenCV를 정적 라이브러리(static library)로 사용한 c++ 배포용 프로그램 만들기 (100) | 2013.03.28 |
---|---|
OpenCV 핸드북 (cheatsheet) (63) | 2013.02.27 |
OpenCV 마우스 이벤트 처리하기 (9) | 2013.02.14 |