Page 1 of 1

Read gif with Magick++, process frames with OpenCV, save back to gif with Magick++

Posted: 2018-11-22T08:56:51-07:00
by ips11235
Hello,

I am writing a program in c++ that uses Magick++ API and OpenCV. The idea is that program reads a gif image, does some image processing with OpenCV on the frames and saves the frames back to a gif image.

After some experimenting, I realized that when the frames from gif are processed with Magick++ API the saved results are correct (not distorted).

My problem is that I read the gif file with Magick++ then loop through frames, convert them to OpenCV structure Mat, do some image processing, convert them back to Magick++ Image class and write back to miff (or gif).

In this process the header information from the original miff (gif) is lost.
Is there a way to do this without the loss of information from the original gif?

The image used: image.gif

Here is the code that reads gif and saves it as miff (Magick++ API):

Code: Select all

list<Image> imageList;
readImages( &imageList, "image.gif" );
writeImages(imageList.begin(),imageList.end(),"image.miff");
An example header from saved miff file:

id=ImageMagick version=1.0
class=PseudoClass colors=64 alpha-trait=Blend
columns=334 rows=200 depth=16
colorspace=sRGB
page=334x200+0+0
iterations=0 delay=10 ticks-per-second=100
dispose=None
rendering-intent=Perceptual
gamma=0.454545
red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
white-point=0.3127,0.329
date:create=2018-11-21T12:55:10+01:00
date:modify=2018-11-20T15:18:07+01:00


Code that reads gif, does some OpenCV image processing, saves as miff:

Code: Select all

list<Image> imageList;
readImages( &imageList, "image.gif" );

list<Image> newList;
for (list<Image>::iterator it = imageList.begin(); it != imageList.end(); it++){  
 	Mat tmp = Magick2Mat(*it);               
        cvtColor(tmp,tmp,cv::COLOR_BGRA2GRAY); 
        Image img = Mat2Magick(tmp);        
        newList.push_back(img);
} 
writeImages(newList.begin(),newList.end(),"tmp/new_image.miff");
Magick2Mat function:

Code: Select all

Mat Mat Magick2Mat(Image& image){
    // Create Magick++ Image object and read image file   
   // Get dimensions of Magick++ Image
   int w=image.columns();
   int h=image.rows();
   // Make OpenCV Mat of same size with 8-bit and 4 channels
    Mat opencvImage(h,w,CV_8UC4);
   // Unpack Magick++ pixels into OpenCV Mat structure
   image.write(0,0,w,h,"BGRA",Magick::CharPixel,opencvImage.data);
   return opencvImage;
}
Mat2Magick function:

Code: Select all

Image Mat2Magick(Mat& src){
    if(src.channels()==4) {        
        Image mgk(src.cols, src.rows, "BGRA", CharPixel, (char *)src.data);
        return mgk;
    }    
    if(src.channels()==3){
        cvtColor(src,src,cv::COLOR_BGR2BGRA);
        Image mgk(src.cols, src.rows, "BGRA", CharPixel, (char *)src.data);
        return mgk;
    }    
    if(src.channels()==1) {      
        cvtColor(src,src,cv::COLOR_GRAY2BGR);
        cvtColor(src,src,cv::COLOR_BGR2BGRA);
        Image mgk(src.cols, src.rows, "BGRA", CharPixel, (char *)src.data);
        return mgk;
    }
}
Resulting miff file header:

id=ImageMagick version=1.0
class=DirectClass colors=0 alpha-trait=Blend
matte=True
columns=334 rows=200 depth=16
colorspace=sRGB
iterations=0 delay=0 ticks-per-second=100
rendering-intent=Perceptual
gamma=0.454545
red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
white-point=0.3127,0.329


Any help is much appreciated.