2011-02-07 2 views
0

FreeImage (FIBITMAP)와 OpenCV 형식 (IplImage 및/또는 Mat)간에 데이터를 교환해야합니다. FreeImage는 OPenCV imageData ptr을 설정할 수있는 FreeImage_GetScanLine 함수를 제공하므로 FIBITMAP에서 데이터를 IplImage 또는 Mat로 가져 오는 것이 좋습니다.OpenCV IplImage 또는 Mat를 Freeimage로 복사 FIBITMAP

그러나 역 분개를 수행하는 방법에 중점을두고 있습니다. 즉, 일단 OpenCV 이미지가 생기면 어떻게 데이터를 FreeImage 이미지로 가져 옵니까?

답변

0

당신은해야 데이터 포인터를 복사하는 것만으로도주의를 기울여야합니다. 많은 이미지 포맷은 새로운 라인을 각각 4 바이트 경계에서 시작하도록 패딩을합니다.

이미지에 GetScanLine() 함수가있는 경우 빈 plImage */cv :: Mat를 만들고 포인터가있는 각 행을 GetScanLine() 및 .ptr() 멤버에서 반환하는 것이 더 안전합니다. : MAt

cv::Mat &src   
int srcRowBytes = width * src.elemSize(); 

for (int ih=0;ih<height;ih++) { 
    memcpy(dest.pointer_to_row(ih),src.ptr(ih),srcRowBytes); 
} 
+0

'IplImage'와'cv :: Mat' 둘 다 정확히이 이유 (패딩)를위한 행 단계를 가지고 있습니다. – etarion

+0

예.하지만 Freeebitmap이 스테핑을 위해 사용하는 것을 찾을 수 있습니까? –

+0

OpenCV의 stepWidth와 마찬가지로 이미지의 너비를 바이트 단위로 반환하는 FreeImage_GetPitch 함수가 있습니다. 나는 곧 이것을 시도 할 것이고, 사람들이 그것이 밖으로 퍼덕 거리는 지 알게 할 것이다. 감사. – SSilk

0

글쎄, 당신이 사본을 신경 쓰지 않는 경우에, 당신은 단지 FIBITMAP에 대한 IplImage*/cv::Mat 헤더를 만들 수 있습니다 다음과 같이합니다 (OpenCV의 기능을 사용하여) 복사 :

cv::Mat src; // your source image 
FIBITMAP whatever; // allocate space for your FIBITMAP here 
cv::Mat wrapper(height, width, CV_8UC3, ptr_from_FIBITMAP, step); 
src.copyTo(wrapper); 
1

다음은 변환을위한 자세한 코드입니다. 어느 라이브러리에도 많은 이미지 데이터 유형이 있습니다. 가장 일반적인 라이브러리를 지원하려고했습니다. 이것은 cv :: Mat를 소스로 전달한다고 가정합니다. FreeImage는 왼쪽 하단의 뷰 시점을가집니다!

/* These are openCV types 
#define CV_8U 0 
#define CV_8S 1 
#define CV_16U 2 
#define CV_16S 3 
#define CV_32S 4 
#define CV_32F 5 
#define CV_64F 6 
*/ 

/* these are FI types 
FIT_UNKNOWN = 0, // unknown type 
FIT_BITMAP = 1, // standard image   : 1-, 4-, 8-, 16-, 24-, 32-bit 
FIT_UINT16 = 2, // array of unsigned short : unsigned 16-bit 
FIT_INT16 = 3, // array of short   : signed 16-bit 
FIT_UINT32 = 4, // array of unsigned long : unsigned 32-bit 
FIT_INT32 = 5, // array of long   : signed 32-bit 
FIT_FLOAT = 6, // array of float   : 32-bit IEEE floating point 
FIT_DOUBLE = 7, // array of double   : 64-bit IEEE floating point 
FIT_COMPLEX = 8, // array of FICOMPLEX  : 2 x 64-bit IEEE floating point 
FIT_RGB16 = 9, // 48-bit RGB image   : 3 x 16-bit 
FIT_RGBA16 = 10, // 64-bit RGBA image  : 4 x 16-bit 
FIT_RGBF = 11, // 96-bit RGB float image : 3 x 32-bit IEEE floating point 
FIT_RGBAF = 12 // 128-bit RGBA float image : 4 x 32-bit IEEE floating point 

*/ 

if(_dib) // get rid of the current dib. 
    FreeImage_Unload(_dib); 


int width = src.size().width; 
int height = src.size().height; 

switch(src.type()) 
{ 
case CV_8U :{_dib = FreeImage_AllocateT(FIT_BITMAP,width, height, 8) ;}break; // 8 bit grayscale 
case CV_8UC3:{_dib = FreeImage_AllocateT(FIT_BITMAP,width, height, 24);}break; // 24 bit RGB 
case CV_16U :{_dib = FreeImage_AllocateT(FIT_UINT16,width, height, 16);}break; // 16 bit grayscale 
case CV_16S :{_dib = FreeImage_AllocateT(FIT_INT16 ,width, height, 16);}break; 
case CV_32S :{_dib = FreeImage_AllocateT(FIT_INT32 ,width, height, 32);}break; 
case CV_32F :{_dib = FreeImage_AllocateT(FIT_FLOAT ,width, height, 32);}break; 
case CV_64F :{_dib = FreeImage_AllocateT(FIT_DOUBLE,width, height, 32);}break; 
default:ASSERT(FALSE); 
} 

if(_dib==NULL) 
    return FALSE; 


int srcRowBytes = width * src.elemSize(); 

for (int ih=0;ih<height;ih++) 
{ 
    BYTE* ptr2Line = FreeImage_GetScanLine(_dib,(height-1)-ih); 
    memcpy(ptr2Line,src.ptr(ih),srcRowBytes); 
} 
_bHasChanged = TRUE; 

return TRUE;