Multithreading issue when using parallel_for_ while running on ubuntu


I am having some issues with some multithreading code. I have written this code a while ago on windows (windows 10, visual studio 2019, openCV 4.3.0 with openMP and TBB off), now I want to run it on ubuntu (ubuntu 20.04, visual studio code, gcc 9.4.0, openCV 4.3.0), but it only works when I turn OpenMP on while building OpenCV.
Minimal example of the code:
.cpp file

namespace Foo {
class ExampleClass : public cv::ParallelLoopBody {
  ExampleClass(const cv::Mat& _srcmat, cv::Mat& _dstmat)
      : ParallelLoopBody(), srcmat_(_srcmat), rgb_dst_mat_(_dstmat) {

  void operator()(const cv::Range& range) const CV_OVERRIDE {
    int col = 1;
    int row = range.start;
    auto src_image = srcmat_;
    auto dst_image = rgb_dst_mat_;
    for (; col < src_image.cols; col++) {
      float R =<float>(row, col) * 10;
      float G =<float>(row, col) * 1;
      float B =<float>(row, col) * 2;
      dst_image.ptr<float>(row, col)[0] = R;
      dst_image.ptr<float>(row, col)[1] = G;
      dst_image.ptr<float>(row, col)[2] = B;

  cv::Mat srcmat_;
  cv::Mat rgb_dst_mat_;

void Example::function(const cv::Mat& src_image, cv::Mat& dst_image) {
  if (src_image.empty()) {
    throw std::invalid_argument("Provided src_image image is empty");

  if (src_image.type() != CV_32FC1 || dst_image.type() != CV_32FC3) {
    throw std::invalid_argument("Invalid image type");

  if (src_image.size() != dst_image.size()) {
    throw std::invalid_argument("Image size is not the same");

  int width = src_image.cols;
  int height = src_image.rows;

  cv::parallel_for_(cv::Range(1, height - 1), ExampleClass(src_image, dst_image));
}  // namespace Foo

.hpp file

namespace Foo {
class Example {
  virtual ~Example();
  static void function(const cv::Mat& bayer, cv::Mat& rgb);
}  // namespace Foo

This will result in a correct image in Windows, but in Ubuntu only when openMP is set to ON when compiling OpenCV.

Ubuntu - OpenMP: OFF, TBB: OFF

Ubuntu - OpenMP: OFF, TBB: ON

Ubuntu - OpenMP: ON, TBB: OFF

I do have a few questions after getting those results:

  1. What is the difference between OpenMP and TBB? What I understand is that both are multithreading libraries, but are working differently. How do they each work?
  2. Why can I run my program on Windows without building any of those two libraries, but do I have to compile OpenMP on Ubuntu?
  3. We suspect there is an interference with different multithreading platforms (parallel_for_ and main thread). Is that possible here? And is there a way to detect automatically which one should be used?

Thanks in advance!

you only work on a single row per operator() call.

I suspect that range tells you to work on several rows.

Yes, when calling ExampleClass, I have entered a range for several rows.