the output of cv::imwrite vs cv::imencode - c++

Does cv::imencode have an identical behavior to cv::imwrite when converting cv::Mat to JPEG? I know that first one write to buffer and the second write to file but I am asking about the written content.

when you call cv::imwrite() it did not call cv::imencode() internally! both functions uses internal ImageEncoder. take a look at loadsave.cpp

Related

LZ4_decompress_safe vs LZ4_decompress_safe_partial

What is the difference between LZ4_decompress_safe and LZ4_decompress_safe_partial? I understand that LZ4_decompress_safe_partial does partial decompression, but it looks like LZ4_decompress_safe also can do partial decompression or I am wrong. Both function signatures have input and output buffers and both have sizes of those buffers as function arguments. And that's why I am asking about it. Say I have a buffer with compressed data and want to decompress only a portion of it. What would be the difference between using LZ4_decompress_safe and LZ4_decompress_safe_partial. Would I get the same result?
it looks like LZ4_decompress_safe also can do partial decompression
That's incorrect.
LZ4_decompress_safe() is expected to decompress full blocks, only.
It will return an error code if one tries to use it for partial decompression.
Generally speaking, LZ4_decompress_safe_partial() is more powerful, because it can do both full and partial blocks. That being said, its strength is its weakness : if your application wants to know if the block was fully decoded or not, LZ4_decompress_safe_partial() will not provide a useful signal for that: it will happily stop in the middle of the block if instructed to do so. It's also slightly more complex, internally, which may result in slightly slower decoding speed.

Is there a general way to detect file write errors with c++?

I have an application that writes several files depending on the specific config. Sometimes we use the normal std:ostream, sometimes we write with opencv, or with boost.
For std:ostream rdstate() function.
In my opinion the best solution would be, if I could use some general method (e.g. from the os), that works for each mechanism.
Is there something like this?
If not, can anyone point me to documentation about checks similar to rdstate()?
Thanks
Update:
I write the files with these functions:
OpenCV: cv::VideoWriter << image
boost: boost::iostreams::file_sink->write
I found a way to check the written data for the bosst case. The write function returns the number of written bytes, and I can compare this to the expected bytes.
For the openCV case I used GetFileAttributesEx the determine the filesize and check if that increases.
Is that a good way?
If the underlying operating system call that writes to a file returns an error indication, I would expect std::ostream to end up in a fail() state.
You just have to be diligent about checking the status of the std::ostream, including after an explicit close(), since a write error could be encountered writing out the final bits of buffered data.

Is it safe converting a Mat to itself with different type?

Suppose I want to use a Mat as float. The following code can be compiled without error. However, is it safe doing this?
Mat im = imread('test.jpg', CV_LOAD_IMAGE_GRAYSCALE);
im.convertTo(im, CV_32F1);
I want to do this because it's written more compact, otherwise I need to create a temporary Mat.
The documentation of Mat::convertTo() doesn't give much information about the memory usage of the function.
Mat::convertTo function should be safe to use when using inplace calls (i.e. same input and output Mat objects).
According to OpenCV DevZone, this function did have a bug when using inplace calls, but it was fixed a few years ago.

C++: fread() returns non-zero, but only inserts zeros in to buffer

I am using fread() in C++ to read very large binary files (100MB-2GB). The binary files are originally written from C++ by outputting a series of "packets". The packets are made of a "header" struct (that contains a size field) being directly written to a file, and then binary content with size equal to the size written in to the header. When reading the files, the packets are looped over, the header is read in to a struct and the content is read in to a void pointer of the size provided in the header.
This is a known working method already implemented in other tools (meaning I can validate the files I am trying to read). Assume all files we are working with are validated. In at least one file, my implementation of reading a binary file is working correctly.
However, with another file fread() starts acting funky for no apparent reason. After many successful reads, I cleanly read the header portion of a packet using:
if (sizeof(stHdr) != fread((void *)&stHdr, 1, sizeof(stHdr), fi))
By cleanly reads, I mean fread() returns "sizeof(stHdr)" as expected, and feof(fi) and ferror(fi) both return 0. However... stHdr is completely filled with all zeros; the value of every field in stHdr contains 0x0. I have validated the binary file to be correctly formed, and to have data at the point that I am reading.
Has anyone seen this before or know what could be causing it?
Thanks!
If your files are over 2GB, you'll need to enable large file support.
The quick and easy way to do this is to compile with -D_FILE_OFFSET_BITS=64. For the more targeted ways, and more details, see http://www.suse.de/~aj/linux_lfs.html
The problem ended up being a classic case of PEBKAC...
Apparently my binary file did become corrupted at some point and actually did have a bunch of 0s in it. I had copied it directly out of a repository and the file was validated before being put in to the repo, so I assumed it was good. Apparently something bad happened to my local version of the file and was the source of my problems.

OpenCV - IplImage

What is IplImage in OpenCV? Can you just explain what is meant by it as a type? When should we use it?
Thanks.
Based on the 'c++' tag you have in your question:
You should not use it, you should use cv::Mat. Every IplImage is a cv::Mat internally.
IplImage is only used in the C API. It is a kind of CvMat and holds image data. Its name originates from OpenCV's roots (Intel IPL).
It is not relevant anymore if you use the C++ API of OpenCV.
IplImage and cv::Mat are different header types for matrix/image data. They're basically compatible with each other, but IplImage is used in OpenCV's C API, while cv::Mat is used in the new C++ API.
When you decide to use OpenCV's C API, you will mostly use IplImages. Otherwise you will mostly use cv::Mats.
Of course, you can convert IplImages and cv::Mats to each other, e.g.
cv::Mat mat(myIplImage);
In this case, they share the same underlying data, i.e. modifications made through either header will be visible regardless of what header you're using to access the data.
Deep-copy (not only header is "transformed"/copied, but also the underlying data) is possible with
cv::Mat mat(myIplImage, true)
Note that multiple IplImages can also point to the same underlying data, as can multiple cv::Mats.
When working with OpenCV and similar libraries it is important to notice that cv::Mats and IplImages are only "headers" for the actual data. You could say that cv::Mats and IplImages are basically pointers plus important meta information like number of rows, columns, channels and the datatype used for individual cells/pixels of the matrix/image. And, like real pointers, they can reference/point to the same real data.
For example, look at the definition of IplImage: http://opencv.willowgarage.com/documentation/basic_structures.html#iplimage
The most important member is char *imageData;. This pointer references the actual image data. However, the IplImage as a whole contains meta information about the image as well, like number of rows and columns.
The IplImage structure was inherited from the Intel Image Processing Library, in which the format is native. OpenCV only supports a subset of possible IplImage formats, as outlined in the parameter list above.
If you are usin C++ you don´t use IplImage because this only use in a C program, (IplImage is in C API).
In addition if you are usin C you need post Cv before the variables names: "CvMat *" "CvPoint " "IplImage " etc.
It ´s better to use C++ code, you don´t use Cv: "Mat *" etc. but you can´t use the IplImage type, instead of IplImage you use a Mat type for example in findchessboardcorner function.