OpenCV 를 사용하다보면 이미지를 저장하는 배열의 형태가 사람마다 각각 다를 경우를 겪으신  분들이 있을겁니다.

 

예를들어 다른 선구자들이 만들어 놓은 소스코드를 참고하고자 할때, CvMat, cv::Mat, IplImage, CvArr 등등 각각 다른 포멧을 사용하는것을 보신 분들이 있을텐데요,

 

저도 이러한 경우를 자주 겪어서 정리 겸, 정보 공유 겸, 오랫만에 포스팅 겸.. 해서 글을 적게 되었네요.

 

 

 

 

//OpenCV 이미지 변환
//Mat & CvMat & IplImage, CvArr convert function

IplImage to->

 

IplImage* -> cv::Mat

1. Mat Mat_img(IplImage_img);

2. Mat Mat_img = cvarrToMat(IplImage_img);

 

IplImage* -> CvMat

cvGetMat( IplImage_img, &CvMat_img);

 

 

 

cv::Mat to->

 

cv::Mat -> IplImage*

IplImage *IplImage_img = new IplImage(Mat_img);

 

cv::Mat -> CvMat

CvMat CvMat_img = Mat_img; // convert directly

 

 

 

CvMat to->

 

CvMat -> IplImage*

IplImage *IplImage_img = cvGetImage(CvMat_img);

 

CvMat -> cv::Mat

Mat Mat_img(CvMat_img);

 

 

 

 

 

 

 

 

Referenced:

http://docs.opencv.org/index.html

http://v_lovepooh_v.blog.me/20170546845

http://blog.naver.com/makerslee/30146885035

http://codens.info/386

http://www.cyworld.com/fish_blog/4695785

Posted by Tommy™
,

역시나 오늘도 작업하다가 알게된 사소하지만 나름? 유익한 정보를 공유하고자 한다.

 

물론 알고 계신분들은 많으실거라 보지만, 난 몰랐기에...

 

일단 기본적으로 웹캠으로 부터 영상을 얻어오면 640X480 사이즈이다.

(예전에는 320X240 이었던 시절이..)

 

하지만,

 

요즘에는 FullHD 화질을 지원하는 웹카메라들이 많다.

 

그중에 나는 Microsoft 사의 LifeCam - Studio 모델을 사용한다.

 

그래서 OpenCV를 활용하여 1080p FullHD 영상을 매프레임 얻어오고자 하는데,

 

아무리해도 640X480 영상밖에 얻어오질 못했다.

 

그래서 구글링 하던 결과..

 

하나의 솔루션을 찾았는데,

 

링크 참조 : http://stackoverflow.com/questions/15768260/get-maximum-resolution-when-capturing-image-data-with-cvqueryframe

 

 

 

m_pCapture = cvCreateCameraCapture(0);

 

후에

 

cvSetCaptureProperty(m_pCapture,CV_CAP_PROP_FRAME_WIDTH,1920);
cvSetCaptureProperty(m_pCapture,CV_CAP_PROP_FRAME_HEIGHT,1080);

 

이렇게 하면 카메라 파라미터를 1920X1080 으로 세팅 해줌으로써 문제없이 FullHD 영상을 매 프레임 캡쳐할 수 있었다.

 

 

Posted by Tommy™
,

 

 

 

 

 

현재 하고 있는 프로젝트에서 cvReleaseCapture() 를 하게 되면 계속 프로그램이 정상적으로 release 되지않고 메모리릭을 발생시키면서 그냥 죽어버린다.

 

도대체 뭐가 문제일까....

 

참고 주소 : http://onbranding.kr/6

 

위 블로그를 통해 그 답을 얻을수 있었는데,

 

인용하면..

 

 

 

 

cvRetrieveFrame 함수나 cvQueryFrame 함수 등을 이용해 카메라에서 프레임을 받아넣은 IplImage 구조체는 따로 Release해주어서는 절대 안된다!!

 

 

 

 

그런데 나는 프레임을 받아넣은 IplImage 구조체를 먼저 cvReleaseImage() 해줬으니 계속 프로그램이 죽을수 밖에 없지 아니한가!

 

즉 할당한 구조체의 메모리를 반환하려는데, 이미 반환해버렸으니 접근자 에러로 인해 프로그램이 뻗는 논리인셈..

 

오늘도 새로운것 하나 알게 되었군 ^^

 

 

 

 

 

Posted by Tommy™
,

나는 현재 OpenCV 2.4.2 버전을 사용중에 있다.

 

요즘 예전에 사용했던 소스들을 사용할일이 있어서 그대로 긁어와서 사용하는데,

 

잘 동작하던 cv함수들이 자꾸 말썽을 일으키는것이다.

 

계속 Critical error를 발생하는데, 아무리봐도 메모리 참조를 잘못하게되어 생기는거 같았다.

 

도대체가 뭐가문제지.. 싶어, 이번에 갈아탄 64비트 컴퓨터 때문인가?? 생각되어 어제저녁부터, 아침 출근하여 계속 구글링 및 openCV카페, 그리고 네이년등 모든 검색을 통해 찾아보았다.

 

하지만.. 설마설마.. 하는 마음에 처음 64비트로 갈아탔을때의 문제가 되었던 tbb.dll 파일이 의심스러워지기 시작했다.

 

그래서 openCV 가 설치된 경로로 들어가서 보니, 떡~하니 tbb.dll 이 존재하는것이었다.

 

경로 : OpenCV 설치한 경로\opencv\build\common\tbb\ia32\vc10

 

설마설마 하면서 system32 및 64에 복사를 해놓고 모두 재컴파일을 한하니..

 

빙고~!! 잘 동작했다.

 

이넘의 tbb.dll파일을 인터넷에서 아무렇게나 다운받았더니 이러한 문제가 발생했다.

 

혹시나 다른사람들도 문제가 생길수 있으니 참고하시길...

 

(64비트로 갈아탄지 벌써 2주일 다되어가는데, 개발에 있어서는 전혀 문제가 될게 없는거 같다. 현.재.까.진.

 

왜냐하면 32비트용으로 개발하고 있으니말이다, 처음에 생각한대로 int형이 8바이트면 어떻하지.... 라는 생각은 괜한 기우였나 보다.

 

어째뜬 문제 해결 완료!!

 

오늘도 즐공 및 코딩~~!!)

Posted by Tommy™
,

몇일전 OpenCV 2.4 버전이 릴리즈 되었다.

 

새로운 기능들이 많이 추가되고 한거같은데, 뭐 나의 관심 밖이니..

 

뭐 어째뜬 난 2.0 버전이 최신 버전일때부터 꾸준히 써왔는데, 이번에 작업하는 부분에서 동영상을 재생시켜야 했다.

 

잘 되려니 했는데.. 재생이 안되고 이런저런 문제점들이 급수기하적으로 막 쏟아지는거였다..

 

제일 중요한건 cvCreateFileCapture() 함수가 계속 파일을 못읽어들이고 NULL값을 리턴하는것이었다.

 

그래서 결국 2.4버전으로 갈아타고나서는 동영상 재생문제도 바로 해결,

 

하지만, 다른 커다란 문제점이 발생했다.

 

2.0버전만 써오던 나로써는 2.2 버전 Release 되었을때 CvvImage 클래스가 사라진것을 몰랐다..!! 젠장!!

 

그래서.. 이리저리 구글링하다가 나랑 같은 증상을 겪는 사람들이 많은걸 알고, 직접 구현??까진 아니구 취합해서 같은 기능을 하게 만들어보자고 생각해서 작업을 몇시간 진행했는데, 다행히 잘 구동 된다. 기존의 것과 똑같이!!

 

원래 CvvImage 클래스내부의 DrawToHDC()함수를 직접 구현했는데, 아래 소스코드도 첨부하겠다.

 

물론 소스코드는 본인이 취합한거라 지저분하거나 맘에 안드는 부분이 있을것인데, 쓸사람만 쓰길..

 

 

void CCV_Mgr::DrawToHDC(IplImage* pImage, HDC dc, RECT* rect)
{
    if( rect && pImage && pImage->depth == IPL_DEPTH_8U && pImage->imageData )
 {
  uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
  BITMAPINFO* bmi = (BITMAPINFO*)buffer;
  int bmp_w = pImage->width, bmp_h = pImage->height;
  CvRect roi = cvGetImageROI( pImage );
  CvRect dst = RectToCvRect( *rect );
  if( roi.width == dst.width && roi.height == dst.height )
  {
   Show( pImage, dc, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y );
   return;
  }
  if( roi.width > dst.width )
  {
   SetStretchBltMode(
       dc,           // handle to device context
       HALFTONE );
  }
  else
  {
   SetStretchBltMode(
       dc,           // handle to device context
       COLORONCOLOR );
  }
  FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(pImage), pImage->origin );
  ::StretchDIBits(
   dc,
   dst.x, dst.y, dst.width, dst.height,
   roi.x, roi.y, roi.width, roi.height,
   pImage->imageData, bmi, DIB_RGB_COLORS, SRCCOPY );
 }
}

void CCV_Mgr::Show( IplImage* pImage, HDC dc, int x, int y, int w, int h, int from_x, int from_y )
{
 if( pImage && pImage->depth == IPL_DEPTH_8U )
 {
  uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
  BITMAPINFO* bmi = (BITMAPINFO*)buffer;
  int bmp_w = pImage->width, bmp_h = pImage->height;
  FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(pImage), pImage->origin );
  from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 );
  from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 );
  int sw = MAX( MIN( bmp_w - from_x, w ), 0 );
  int sh = MAX( MIN( bmp_h - from_y, h ), 0 );
  SetDIBitsToDevice(
   dc, x, y, sw, sh, from_x, from_y, from_y, sh,
   pImage->imageData + from_y*pImage->widthStep,
   bmi, DIB_RGB_COLORS );
 }
}

void CCV_Mgr::FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
{
 assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));

 BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
 memset( bmih, 0, sizeof(*bmih));
 bmih->biSize = sizeof(BITMAPINFOHEADER);
 bmih->biWidth = width;
 bmih->biHeight = origin ? abs(height) : -abs(height);
 bmih->biPlanes = 1;
 bmih->biBitCount = (unsigned short)bpp;
 bmih->biCompression = BI_RGB;

 if( bpp == 8 )
 {
  RGBQUAD* palette = bmi->bmiColors;
  int i;
  for( i = 0; i < 256; i++ )
  {
   palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
   palette[i].rgbReserved = 0;
  }
 }
}

int CCV_Mgr::Bpp(IplImage* pImage)
{
 return pImage ? (pImage->depth & 255)*pImage->nChannels : 0;
}

CvRect CCV_Mgr::RectToCvRect(RECT rect)
{
 rect = NormalizeRect( rect );
 return cvRect( rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top );
}

RECT CCV_Mgr::NormalizeRect( RECT r )
{
 int t;

 if( r.left > r.right )
 {
  t = r.left;
  r.left = r.right;
  r.right = t;
 }

 if( r.top > r.bottom )
 {
  t = r.top;
  r.top = r.bottom;
  r.bottom = t;
 }

 return r;
}

'[ Topics ] > OpenCV' 카테고리의 다른 글

cvReleaseCapture() 사용할때 주의사항!  (2) 2013.11.19
tbb.dll Error, 그리고 해결  (0) 2012.09.19
cvFindContours() 함수  (0) 2012.02.13
나의 구세주 : cvPointPolygonTest()  (0) 2012.02.09
Opencv Contour 구하는 부분  (0) 2010.12.10
Posted by Tommy™
,