-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Closed
Closed
Copy link
Labels
Description
Describe the feature and motivation
In OpenCV 4.11, we have to update the channel handling for GIF Decoder.
IMREAD_UNCHANGED
It doesn't handle Transparent Color Flag bit in packed fields for readHeader().
When input GIF stream has 3ch RGB without alpha channels, 'm_type' should be CV_8UC3.
But now it is CV_8UC4 constantly. So imread(cv::IMREAD_UNCHANGED) cannot return CV_8UC3.
IMREAD_GRAYSCALE
GIF decoder expects that destination mat has 3 or 4 channels.
imread(cv::IMREAD_GRAYSCALE) request 1 channel image destination.
We have to fix it.
Additional context
diff --git a/modules/imgcodecs/test/test_gif.cpp b/modules/imgcodecs/test/test_gif.cpp
index b9c49c0bdb..ae0064f619 100644
--- a/modules/imgcodecs/test/test_gif.cpp
+++ b/modules/imgcodecs/test/test_gif.cpp
@@ -246,6 +246,7 @@ TEST(Imgcodecs_Gif, read_gif_special){
cv::Mat png_img1;
ASSERT_NO_THROW(png_img1 = cv::imread(png_filename1,IMREAD_UNCHANGED));
ASSERT_FALSE(png_img1.empty());
+ cv::cvtColor(png_img1, png_img1, cv::COLOR_BGRA2BGR);
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), gif_img1, png_img1);
cv::Mat gif_img2;
ASSERT_NO_THROW(gif_img2 = cv::imread(gif_filename2,IMREAD_UNCHANGED));
@@ -253,6 +254,7 @@ TEST(Imgcodecs_Gif, read_gif_special){
cv::Mat png_img2;
ASSERT_NO_THROW(png_img2 = cv::imread(png_filename2,IMREAD_UNCHANGED));
ASSERT_FALSE(png_img2.empty());
+ cv::cvtColor(png_img2, png_img2, cv::COLOR_BGRA2BGR);
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), gif_img2, png_img2);
}
@@ -351,6 +353,21 @@ TEST(Imgcodecs_Gif, write_gif_multi) {
EXPECT_EQ(0, remove(gif_filename.c_str()));
}
+TEST(Imgcodecs_Gif, encode_IMREAD_GRAYSCALE) {
+ cv::Mat src;
+ cv::Mat decoded;
+ vector<uint8_t> buf;
+ vector<int> param;
+ bool ret = false;
+
+ src = cv::Mat(240,240,CV_8UC3,cv::Scalar(128,64,32));
+ EXPECT_NO_THROW(ret = imencode(".gif", src, buf, param));
+ EXPECT_TRUE(ret);
+ EXPECT_NO_THROW(decoded = imdecode(buf, cv::IMREAD_GRAYSCALE));
+ EXPECT_FALSE(decoded.empty());
+ EXPECT_EQ(decoded.channels(), 1);
+}
+
}//opencv_test
}//namespace
diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp
index 947e560c81..f44e64ec7a 100644
--- a/modules/imgcodecs/test/test_grfmt.cpp
+++ b/modules/imgcodecs/test/test_grfmt.cpp
@@ -164,6 +164,8 @@ TEST_P(Imgcodecs_ExtSize, write_imageseq)
continue;
if (cn != 3 && ext == ".ppm")
continue;
+ if (cn == 1 && ext == ".gif")
+ continue;
string filename = cv::tempfile(format("%d%s", cn, ext.c_str()).c_str());
Mat img_gt(size, CV_MAKETYPE(CV_8U, cn), Scalar::all(0));
@@ -179,8 +181,14 @@ TEST_P(Imgcodecs_ExtSize, write_imageseq)
ASSERT_TRUE(imwrite(filename, img_gt, parameters));
Mat img = imread(filename, IMREAD_UNCHANGED);
ASSERT_FALSE(img.empty());
- EXPECT_EQ(img.size(), img.size());
- EXPECT_EQ(img.type(), img.type());
+ EXPECT_EQ(img_gt.size(), img.size());
+ EXPECT_EQ(img_gt.channels(), img.channels());
+ if (ext == ".pfm") {
+ EXPECT_EQ(img_gt.depth(), CV_8U);
+ EXPECT_EQ(img.depth(), CV_32F);
+ } else {
+ EXPECT_EQ(img_gt.depth(), img.depth());
+ }
EXPECT_EQ(cn, img.channels());
@@ -200,6 +208,14 @@ TEST_P(Imgcodecs_ExtSize, write_imageseq)
EXPECT_LT(n, 1.);
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
}
+ else if (ext == ".gif")
+ {
+ // GIF encoder will reduce the number of colors to 256.
+ // It is hard to compare image comparison by pixel unit.
+ double n = cvtest::norm(img, img_gt, NORM_L1);
+ double expected = 0.03 * img.size().area();
+ EXPECT_LT(n, expected);
+ }
else
{
double n = cvtest::norm(img, img_gt, NORM_L2);
@@ -238,6 +254,9 @@ const string all_exts[] =
#ifdef HAVE_IMGCODEC_PFM
".pfm",
#endif
+#ifdef HAVE_IMGCODEC_GIF
+ ".gif",
+#endif
};
vector<Size> all_sizes()Reactions are currently unavailable