Read gif with Magick++, process frames with OpenCV, save back to gif with Magick++
Posted: 2018-11-22T08:56:51-07:00
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):
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:
Magick2Mat function:
Mat2Magick function:
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.
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");
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");
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;
}
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;
}
}
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.