【问题标题】:Copy OpenCV IplImage or Mat into Freeimage FIBITMAP将 OpenCV IplImage 或 Mat 复制到 Freeimage FIBITMAP
【发布时间】:2013-03-08 02:14:44
【问题描述】:

我需要在 FreeImage (FIBITMAP) 和 OpenCV 格式(IplImage 和/或 Mat)之间交换数据。我可以将数据从 FIBITMAP 获取到 IplImage 或 Mat 中,因为 FreeImage 为您提供了一个函数 FreeImage_GetScanLine,您可以将 OPenCV imageData ptr 设置为等于。

但是,我被困在如何做相反的事情上,即一旦我有一个 OpenCV 图像,我如何将其数据转换为 FreeImage 图像?

【问题讨论】:

    标签: opencv freeimage


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

      在复制数据指针时你必须小心一点,很多图像格式都有填充以在例如 4 字节边界处开始每一新行。

      如果您的图像具有 GetScanLine() 函数,那么使用从 GetScanLine() 返回的指针和 cv::马特

      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);
      }
      

      【讨论】:

      • IplImagecv::Mat 都有一个行步,正是出于这个原因(填充)。
      • 是的,但是你能找出 Freeebitmap 是用什么来进行步进的吗?
      • 有一个函数 FreeImage_GetPitch 以字节为单位返回图像的宽度,与 OpenCV 的 stepWidth 相同。我会尽快试试这个,如果成功了再告诉你们。谢谢。
      【解决方案3】:

      好吧,如果您不介意复制,您可以为 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);
      

      【讨论】:

        猜你喜欢
        • 2015-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多