OpenCV 4.5.5, VS2019, Windows 10 64-bit or Windows 7 32-bit.
If Intel IPP is enabled, when the cv::Mat data type is 8, 16 or 32 bits of any type and the number of channels is 2 or >=5, or when the data type is double and any number of channels, the cv:: flip() function always throws an ipp::IwException both in Debug and Release mode. Although the flip result is correct, the performance decreases significantly if the function is called frequently. I have to disable Intel IPP with cv::ipp::setUseIPP(false). But I don’t know if this has an impact on other parts of my program.
Here is the test code for this bug.
#include <opencv2\opencv.hpp>
#include <Windows.h>
using namespace std;
template <typename T>
T* CreateArray(const int rows, const int cols, const int channels)
{
const int num = rows * cols * channels;
T* p = new T[num];
if (!p) return NULL;
for (int i=0; i<num; ++i)
*(p + i) = (T)(i + 1);
return p;
}
void DbgTrace(const char *format, ...)
{
va_list args;
va_start(args, format);
char str[512];
vsprintf_s(str, _countof(str), format, args);
OutputDebugString(str);
va_end(args);
}
int main()
{
//cv::ipp::setUseIPP(false); // uncomment this line to eliminate "ipp::IwException" exceptions
const int rows = 7, cols = 5, maxch = 6;
int channels;
const uint delay = 20;
for (channels=2; channels<=maxch; ++channels)
{
if (uchar* array = CreateArray<uchar>(rows, cols, channels))
{
DbgTrace("8UC%d: ", channels);
cv::Mat mat(rows, cols, CV_MAKETYPE(CV_8U, channels), array);
cv::flip(mat, mat, -1); // exception?
Sleep(delay);
mat.release();
delete[] array;
if (channels == 1 || channels == 3 || channels == 4)
DbgTrace("\n");
}
}
DbgTrace("\n");
for (channels=2; channels<=maxch; ++channels)
{
if (ushort* array = CreateArray<ushort>(rows, cols, channels))
{
DbgTrace("16UC%d: ", channels);
cv::Mat mat(rows, cols, CV_MAKETYPE(CV_16U, channels), array);
cv::flip(mat, mat, -1); // exception?
Sleep(delay);
mat.release();
delete[] array;
if (channels == 1 || channels == 3 || channels == 4)
DbgTrace("\n");
}
}
DbgTrace("\n");
for (channels=2; channels<=maxch; ++channels)
{
if (int* array = CreateArray<int>(rows, cols, channels))
{
DbgTrace("32SC%d: ", channels);
cv::Mat mat(rows, cols, CV_MAKETYPE(CV_32S, channels), array);
cv::flip(mat, mat, -1); // exception?
Sleep(delay);
mat.release();
delete[] array;
if (channels == 1 || channels == 3 || channels == 4)
DbgTrace("\n");
}
}
DbgTrace("\n");
for (channels=2; channels<=maxch; ++channels)
{
if (float* array = CreateArray<float>(rows, cols, channels))
{
DbgTrace("32FC%d: ", channels);
cv::Mat mat(rows, cols, CV_MAKETYPE(CV_32F, channels), array);
cv::flip(mat, mat, -1); // exception?
Sleep(delay);
mat.release();
delete[] array;
if (channels == 1 || channels == 3 || channels == 4)
DbgTrace("\n");
}
}
DbgTrace("\n");
for (channels=1; channels<=maxch; ++channels)
{
if (double* array = CreateArray<double>(rows, cols, channels))
{
DbgTrace("64FC%d: ", channels);
cv::Mat mat(rows, cols, CV_MAKETYPE(CV_64F, channels), array);
cv::flip(mat, mat, -1); // exception?
Sleep(delay);
mat.release();
delete[] array;
}
}
DbgTrace("\n");
return 0;
}