C++ Mat::convertTo不适用于OpenMP

C++ Mat::convertTo不适用于OpenMP,c++,opencv,openmp,C++,Opencv,Openmp,我在并行区域中使用Mat::convertTo,它不会将矩阵数据转换为特定类型。但我使用其他函数进行了测试,例如cv::threshold、cv::imshow。它很好用。我不知道怎么了。请参阅下面我的代码: // Mat dst is CV_32FC1 if( dst.type() != CV_8UC1) { int rows = dst.rows; #pragma omp parallel num_threads(2)

我在并行区域中使用Mat::convertTo,它不会将矩阵数据转换为特定类型。但我使用其他函数进行了测试,例如cv::threshold、cv::imshow。它很好用。我不知道怎么了。请参阅下面我的代码:

    // Mat dst is CV_32FC1 
    if( dst.type() != CV_8UC1)
    {   
        int rows = dst.rows;
        #pragma omp parallel num_threads(2)
        {
            int numt = omp_get_num_threads();
            int tid = omp_get_thread_num();
            int start = tid*(rows/numt); 
            int end = (tid+1)*(rows/numt);
            if( tid == (numt-1))
            {
                end = rows;
            }

            Mat tmp = dst.rowRange(start, end);
            tmp.convertTo(tmp, CV_8UC1); 
    }
执行并行区域,但dst的类型仍然是CV_32FC1。我的代码有什么问题?任何帮助都将不胜感激

关于,,
Nan

几乎所有在Mat上运行的功能都会检查目标Mat的大小和类型。如果它们是相同的,他们就使用它们。所以,如果你用

threshold(src, src, ...);
它将被就地处理

但是,如果目标mat具有不同的大小、类型、通道数等,它将分配一个新的。在您的示例中:

tmp.convertTo(tmp, CV_OTHER_TYPE);
现在假设dst(实际上是tpm的源)将被更改:

dst(tmp_region_ofInterest).convertTo(dst(region));
但它实际上扩展到了

Mat  tmp2(tmp.size, CV_OTHER_SIZE);
tmp.convertTo(tmp2,...);
tmp = tmp2;
函数退出后,tmp不再是dst的一个区域

原因很简单:首先,不能就地更改类型,也不能更改部分矩阵的类型。你想发生什么?内存中是否有连续的矩阵空间,由无符号字符和浮点混合填充?因为这会发生,至少在处理的某个时刻


因此,始终在文档中检查给定函数是否在适当的位置运行,是否在感兴趣的区域上运行,以及是否可以在感兴趣的区域上运行。此外,还应使用常识来填补官方文件中缺失的空白。

这不可行,因为您没有在任何地方更改dst的类型。代码中还缺少一个括号。谢谢@macs,但我仍然不清楚您的建议。你能给我一段代码什么的吗?因为Mat::rowRange为dst的行范围创建了新的标题。所以,如果我转换tmp的类型,为什么dst类型仍然是旧类型。对不起,我问了个无聊的问题。我是opencv的新手这是因为您正在创建dst.rowRange的副本。因此,当更改tmp的类型时,您并没有更改dst的类型。如果您能提供更多的代码,这也会很有帮助。现在这个算法对我来说没有什么意义。@macs这是所有与这个问题相关的代码。多亏了你,现在我有点明白了。我只想分割每个线程的图像数据,以便在不克隆任何内容的情况下执行。有没有办法做到这一点?您应该直接在并行环境中执行使用此数据的函数。每个线程在tmp上执行计算,完成后必须合并输出数据。合并的结果可以再次转换为所需的数据类型。对你有意义吗?