OpenCV output monochrome TIFF group 4 compression - c++

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'

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);
}

Related

How to compile C++ code that contains OpenCV library without Makefile?

I just started learning OpenCV with C++. I built OpenCV from source on Linux machine. I use Visual Studio Code text editor. I want to compile C++ code that contains OpenCV library without Makefile. I added /usr/local/opencv4/** to includePath variable. But it didn't work. I'm receiving opencv2/opencv.hpp error. Is it possible build C++ code that contains OpenCV includes without Makefile? How can I do it?
My Code
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat image = imread("Enter the Address"
"of Input Image",
IMREAD_GRAYSCALE);
if (image.empty()) {
cout << "Image File "
<< "Not Found" << endl;
cin.get();
return -1;
}
imshow("Window Name", image);
waitKey(0);
return 0;
}
You will have to tell the compiler the location of the header files and library files. As mentioned by kotatsuyaki you can use pkg-config to do this for your.
Example with gcc and pkg-config:
g++ *.cpp -o program_name `pkg-config --cflags --libs opencv4`
Example with gcc and without pkg-config:
g++ *.cpp -o program_name -I/PATH/TO/OPENCV/INCLUDE/FOLDER -L/PATH/TO/OPENCV/LIB/FOLDER -lopencv_something -lopencv_somethingelse ... etc
In Windows with cl you can do the same as the g++ without pkg-config:
cl main.cpp /I"PATH TO OPENCV ICNLUDE FOLDER" /link /LIBPATH:"PATH TO OPENCV LIB FOLDER" opencv_library1.lib opencv_libarary2.lib ... etc.

Compiling OpenCV Based Script With G++

I want to begin writing saying that I know that this topic has been talked about multiple times. I can see several posts with similar titles as I'm typing this now. The reason that I'm asking this question once again is because I've tried what those posts stay, and it still won't work. I've copied a simple script that upscales an image using opencv in C++ to begin the learning journey and to make a script that I hope to use in the future very often, maybe even share on GitHub. With that being said, here's more detail about my issue.
In my IDE, Visual Studio Code, my include path has been set to "/opt/homebrew/Cellar/opencv/4.6.0/include/opencv4/".
I've tried using the -I arguments, -l arguments, whatever this is: "pkg-config --cflags --libs opencv4", but none of that worked.
The only time that I could get it to work is using the following command, but even then, g++ returned: fatal error: too many errors emitted, stopping now [-ferror-limit=] 41 warnings and 20 errors generated.
Here's the program that I have:
#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main() {
Mat frame = imread("/Users/karsoneskind/Desktop/Programming/C++/ibootimformer/tests/image.jpg");
namedWindow("Output", 0);
namedWindow("Input", 0);
Mat output;
resize(frame, output, Size(1000, 200), 0, 0);
imshow("Output", output);
imshow("Input", frame);
waitKey(0);
}
Edit: This is the command in terminal I used to try to compile the code:
g++ test.cpp -o test pkg-config --cflags --libs opencv4

Can't cross-compile opencv linux-arm on c++ for RPI

(This is the first time I ask question in stackoverflow. And I'm not fluent in English. sorry for not asking clearly)
I am trying to cross-compile opencv based c++ code on Ubuntu(using virtual box) and try to use it on RPI 4.
I use Ubuntu 16.04(using virtual box) and downloaded OpenCV 4.0.1 refer to this site https://webnautes.tistory.com/1030?category=704653
And I down loaded cross-compiiler by sudo apt-get install git gcc-arm-linux-gnueabihf make ncurses-dev build-essential
After that I wrote c++ code like this.
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int ac, char** av){
Mat img =imread("/home/laboman/ex/ex.jpeg", 0);
Mat img_edge;
Canny(img, img_edge, 50, 200);
imshow("original", img);
imshow("img_edge", img_edge);
waitkey(0);
return 0;
}
It works well when I just compile it on Ubuntu.
But when I tried to cross-compile it
arm-linux-gnueabihf-gcc -o qwer /home/laboman/ex/ex.cpp $(pkg-config opencv4 --libs --cflags) -std=c++11
it came out with an error
/usr/local/lib/libopencv_gapi.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
First, I thought there are no libopencv_gapi.so on /usr/local/lib but there were on that file.
I think the problem is that arm-linux cannot cognize(I'm not sure this is right word) the opencv when cross-compiling.
Don't know how cross-compiling can cognize the opencv.
Please tell me what I have to do?
P.S. I also tried old version of OpenCV OpenCV 2.4.9.1

‘Mat’ was not declared in this scope opencv

I followed this guide to install openCV on Ubuntu:
https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html
When I try to execute the following program:
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <math.h>
#include <tiffio.h>
using namespace std;
int main(){
string imageName("images/400nm.tif");
TIFF* tif = TIFFOpen(imageName.c_str(), "r");
Mat image;
return 0;
}
I get the following error executing the command "g++ ssim.cpp -o ssim -ltiff":
ssim.cpp: In function ‘int main()’: ssim.cpp:19:3: error: ‘Mat’ was
not declared in this scope Mat image; ^~~ ssim.cpp:19:3: note:
suggested alternative: In file included from
/usr/local/include/opencv2/core.hpp:59:0,
from /usr/local/include/opencv2/core/core.hpp:48,
from ssim.cpp:2: /usr/local/include/opencv2/core/mat.hpp:771:18: note: ‘cv::Mat’
class CV_EXPORTS Mat
Does somebody know why I get this and how to solve it?
I'm new at using opencv and libtiff so I have no idea about what to do to solve...
It's not really necessary to build openCV from source. Try installing it with
sudo apt-get install libopencv-dev
and try to compile it again.
Also like you said in your comment, make sure you either use namespace cv or cv::Mat.
Using the command:
g++ ssim.cpp -o ssim -ltiff -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs
I don't get compiler errors but when I try to execute the command ./ssim I get:
./ssim: error while loading shared libraries: libopencv_core.so.3.4: cannot open shared object file: No such file or directory

Using cvLoad I get Unspecified error (The node does not represent a user object (unknown type?)) error

here is the full error message:
OpenCV Error: Unspecified error (The node does not represent
a user object (unknown type?)) in cvRead, file
/home/abe/Documents/opencv-2.4.6.1/modules/core/src/persistence.cpp, line 4997
I saw on google that this might be a bug here
http://opencv-users.1802565.n2.nabble.com/face-detection-cvLoad-td4467872.html
here is how im running it
#include <cv.h>
#include <highgui.h>
using namespace std;
int main()
{
cvLoad("/home/abe/Documents/opencv-2.4.6.1/data/haarcascades/haarcascade_frontalface_alt2.xml");
return 0;
}
many programs load xml files with this function and this file is from opencv directory so i know its good I tried the workaround using cvErode in the above link but still got same error any help is appreciated
btw compile on ubuntu raring with this which works for every other program
g++ b.cpp -o b `pkg-config --cflags --libs opencv`