FreeImage的使用及 opencv讀取gif


因為要用opencv對gif進行處理,查了下,發現有個 FreeImage 的庫 可以用。

FreeImage官網: http://freeimage.sourceforge.net/

下載后,拷貝出 FreeImage.dll FreeImage.lib, FreeImage.h 這是有用的文件。很奇怪這個項目居然沒有文檔說明,只有一些exmaple。

直接貼代碼吧,節省時間。這個例程是可以直接讀取gif的每一幀然后顯示的。

//gif2ipl.cpp
#include <cv.h> 
#include <highgui.h> 
#include "FreeImage.h" 
IplImage*  gif2ipl(const char* filename) 

    FreeImage_Initialise();         //load the FreeImage function lib 
    FREE_IMAGE_FORMAT fif = FIF_GIF; 
    FIBITMAP* fiBmp = FreeImage_Load(fif,filename,GIF_DEFAULT); 
    FIMULTIBITMAP * pGIF=FreeImage_OpenMultiBitmap(fif,filename,0,1,0,GIF_PLAYBACK);
    //  FIBITMAPINFO fiBmpInfo = getfiBmpInfo(fiBmp); 
    int gifImgCnt=FreeImage_GetPageCount(pGIF);
    FIBITMAP * pFrame;
    int width,height;
    width=FreeImage_GetWidth(fiBmp);
    height=FreeImage_GetHeight(fiBmp);
    IplImage * iplImg = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3); 
        iplImg->origin = 1;//should set to 1-top-left structure(Windows bitmap style) 
    RGBQUAD* ptrPalette =new RGBQUAD; // = FreeImage_GetPalette(fiBmp); 
    BYTE intens; 
    BYTE* pIntensity = &intens; 
    cvNamedWindow("gif",0);
    printf("gifImgCnt %d \n",gifImgCnt);
    for (int curFrame=0;curFrame<gifImgCnt;curFrame++)
    {
        pFrame= FreeImage_LockPage(pGIF,curFrame);
        //ptrPalette = FreeImage_GetPalette(pFrame); 
        char * ptrImgDataPerLine;
        for (int i=0;i<height;i++) 
        { 
            ptrImgDataPerLine = iplImg->imageData + i*iplImg->widthStep; 
            for(int j=0;j<width;j++) 
            { 
                //get the pixel index  
                //FreeImage_GetPixelIndex(pFrame,j,i,pIntensity);   
                FreeImage_GetPixelColor(pFrame,j,i,ptrPalette);
                ptrImgDataPerLine[3*j] = ptrPalette->rgbBlue; 
                ptrImgDataPerLine[3*j+1] = ptrPalette->rgbGreen; 
                ptrImgDataPerLine[3*j+2] = ptrPalette->rgbRed; 
                //ptrImgDataPerLine[3*j] = ptrPalette[intens].rgbBlue; 
                //ptrImgDataPerLine[3*j+1] = ptrPalette[intens].rgbGreen; 
                //ptrImgDataPerLine[3*j+2] = ptrPalette[intens].rgbRed; 
            } 
        }
        
        printf("convert curFrame end %d \n",curFrame);
        cvShowImage("gif",iplImg);
        cvWaitKey(30);
        FreeImage_UnlockPage(pGIF,pFrame,1);
    }
    FreeImage_Unload(fiBmp); 
    FreeImage_DeInitialise();    
    return iplImg;

main.cpp:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <highgui.h> 
#include <cv.h> 
#include "opencv2/opencv.hpp"
#include "FreeImage.h" 
 
IplImage*  gif2ipl(const char* filename);
int main(int argc,char* argv[]) 

 
    char* filename = (argc == 2)? argv[1] :(char*)"worldCup.gif"; 
 
    IplImage* iplImg = gif2ipl(filename);  
    cvReleaseImage(&iplImg);//if used gif2ipl function ,we must use cvReleaseImage to avoid memory leak; 
    return 0; 

我用 mingw編譯:makefile:

opencvInclude= -I C:\opencv2.4.4\build\include -I C:\opencv2.4.4\build\include\opencv -I C:\opencv2.4.4\build\include\opencv2
freeimageInclude= -I ../FreeImageLib
cppFlags=-Wall -O2
#cppFlags=-Wall -g

target:main.o gif2ipl.o
    g++ $(cppFlags) -o target main.o gif2ipl.o -L E:\Learn\OpenCV\opencv2.4.4\opencv2.4\build\x86\mingw\lib -lopencv_core244 -lopencv_imgproc244 -lopencv_highgui244  -L../FreeImageLib -lFreeImage

main.o:main.cpp
    g++ $(cppFlags) $(opencvInclude) $(freeimageInclude) -o main.o -c main.cpp

gif2ipl.o:gif2ipl.cpp
    g++ $(cppFlags) $(opencvInclude) $(freeimageInclude) -o gif2ipl.o -c gif2ipl.cpp

.PHONY:clean
clean:
    -del *.o target

實際這個轉換感覺要操作每一個像素比較費時間,能否直接讓 IplImage 的 imageData 指向 FreeImage 讀取數據的那片內存了? 對於單通道圖片,我測試時可以的,但是 gif 似乎最高只支持8位256色,所以如果 IplImage是 8位3通道,就不行了,因為數據的內存布局不同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM