1

Is there a way to output monochrome TIFF files in OpenCV with group 4 compression?

This is the command to do it with imagemagick/graphicsmagick

'gm convert '.$file.' -type bilevel -monochrome -compress group4 '.$output

OpenCV version 4.5.1

update

# g++ -Wall -O3 -std=c++17 main.cpp -o main `pkg-config opencv4 --cflags --libs` -ltiff

find doesn't return anything

root@x:/usr/include/opencv4/opencv2# find . -name "*tif*"

code

#include <tiffio.h>
#include <opencv4/opencv2/opencv.hpp>

std::vector<int> params = {cv::IMWRITE_TIFF_COMPRESSION, COMPRESSION_CCITTFAX4};
cv::imwrite(_output, src_bin, params);

error

[ WARN:0] global ../modules/imgcodecs/src/grfmt_tiff.cpp (914) writeLibTiff OpenCV TIFF(line 914): failed TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor) imwrite_('out.tif'): can't write data: OpenCV(4.5.1) ../modules/imgcodecs/src/grfmt_tiff.cpp:914: error: (-2:Unspecified error) OpenCV TIFF: failed TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor) in function 'writeLibTiff'

clarkk
  • 27,151
  • 72
  • 200
  • 340
  • 1
    I feel you should add the `imagemagick` and `image-processing` tags, so that users with experience can pitch in – Jeru Luke Apr 18 '22 at 11:57

1 Answers1

4

OpenCV uses libtiff (link). If you call cv.imwrite (link) you can pass additional parameters.

For group 4 compression the docs say that you have to pass the IMWRITE_TIFF_COMPRESSION flag (link) with value COMPRESSION_CCITTFAX4 (link).

Example:

#include <tiffio.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

vector<int> params = {IMWRITE_TIFF_COMPRESSION, COMPRESSION_CCITTFAX4};

bool success = imwrite("image.tif", img, params);

Update

Well, this is how it should work. But it seems that opencv4 currently has one or more issues in writing Group 4 TIFF. Btw it's the same when you try the python-lib. This known issue deals with a predictor tag that is wrongly added by opencv. I applied the fix to my local build but after that one more issue came up missing a conversion of the 8bit Mat to 1bit/sample for group4. So my recommendation is:

Workaround

Instead you can use the GraphicsMagick API Magick++.

#include <opencv2/opencv.hpp>
#include <Magick++.h>

using namespace cv;
using namespace Magick;

int main(int argc, char* argv[]) {
        InitializeMagick("");

        Mat img = imread("img.png");
        Image image(img.cols, img.rows, "BGR", CharPixel, (char *)img.data);
        image.compressType(CompressionType::Group4Compression);
        image.write("img.tif");
        return(0);
}
Markus
  • 5,976
  • 5
  • 6
  • 21
  • I'm looking in `/usr/include/opencv4/opencv2` but can't find that header file. I use OpenCV `4.5.1` – clarkk Apr 19 '22 at 11:43
  • `libtiff5-dev is already the newest version (4.2.0-1)` – clarkk Apr 19 '22 at 11:46
  • Which of the two header files are you missing? Have you searched for it on your installation with `find`, yet? – Markus Apr 19 '22 at 12:02
  • 1
    Hi clarkk, seems I have to set up the same versions like you to reproduce. This will take some time until I’m back at office. Btw: I have seen that you have posted the same question 6 years ago [link](https://stackoverflow.com/questions/34222340/compress-output-tiff-with-g4-compression). Has it ever worked for you and what has changed that you are asking again? – Markus Apr 19 '22 at 12:22
  • 1
    I forgot about the question. No it has never worked. I'm not a very experienced in C/C++. This OpenCV thing is actually the only thing I have developed in C++ or C – clarkk Apr 19 '22 at 12:45
  • @clarkk: I have installed a current version of OpenCV and can reproduce your issue. After some research I found this open issue in the opencv-repository: [https://github.com/opencv/opencv/pull/21871]. It addresses the same issue, because opencv sets the predictor tag (317) although it is not applicable to CCITT compression in our case. – Markus Apr 21 '22 at 15:42
  • Ok, so it's an issue with opencv? The github link you posted returns 404 – clarkk Apr 21 '22 at 21:28
  • Sorry, the link was broken due to an extra bracket: https://github.com/opencv/opencv/pull/21871. I've updated the answer with a workaround as long as opencv has issues with group4. Please check! – Markus Apr 21 '22 at 23:13
  • I made a last edit and wrapped up our findings in the answer. Please check! – Markus Apr 25 '22 at 06:35