opencv/modules/videoio
jason_w e8f94182f5
Merge pull request #24180 from MambaWong:4.x
Fixed the channels when capturing yuv422 with v4l2 backend #24180

example to reproduce the problem
```cpp
#include <iostream>

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>

using namespace cv;
using namespace std;

void help_func(VideoCapture& cap) {
  int height      = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
  int width       = cap.get(cv::CAP_PROP_FRAME_WIDTH);
  int pixel_type  = cap.get(cv::CAP_PROP_FORMAT);
  int channels    = CV_MAT_CN(pixel_type);
  int pixel_bytes = CV_ELEM_SIZE(pixel_type);
  bool to_bgr     = static_cast<bool>(cap.get(cv::CAP_PROP_CONVERT_RGB));

  std::cout << "backend: " << cap.getBackendName() << std::endl;
  std::cout << std::hex << "fourcc: " << static_cast<int>(cap.get(cv::CAP_PROP_FOURCC)) << std::endl;
  std::cout << std::boolalpha << "to_bgr: " << to_bgr << std::endl;
  std::cout << std::dec << "height: " << height << " width: " << width << " channels: " << channels
            << " pixel_bytes: " << pixel_bytes << std::endl;

  std::cout << "-----------------------------------------" << std::endl;
}

int main(int, char**) {

  VideoCapture cap;
  cap.open("/dev/video0");
  if (!cap.isOpened()) {
    cerr << "ERROR! Unable to open camera\n";
    return -1;
  }

  {
    help_func(cap);
  }

  {
    cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
    cap.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
    cap.set(cv::CAP_PROP_CONVERT_RGB, 0);
    help_func(cap);
  }

  // {
  //   cap.set(cv::CAP_PROP_CONVERT_RGB, 0);
  //   cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);
  //   cap.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
  //   help_func(cap);
  // }

  Mat frame;
  int frame_idx = 0;
  while (cap.read(frame)) {
    std::cout << "frame index: " << frame_idx++ << std::endl;
    help_func(cap);
    if (frame.empty()) {
      cerr << "ERROR! blank frame grabbed\n";
      break;
    }
    Mat bgr;
    if (cap.get(cv::CAP_PROP_CONVERT_RGB)) {
      bgr = frame;
    } else {
      cv::cvtColor(frame, bgr, cv::COLOR_YUV2BGR_YUYV);
    }

    imshow("frame", bgr);
    if (waitKey(5) >= 0) {
      break;
    }
  }

  return 0;
}
```
The above code will get the wrong channels. By changing lines 41-45 like below, can get the correct channels.
<img width="747" alt="code" src="https://github.com/opencv/opencv/assets/16932438/55f44463-8465-4dba-a979-e71a50d58008">
This is because `cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);` and `cap.set(cv::CAP_PROP_FRAME_WIDTH, 1920);` reinitialize the `frame`, but `cap.set(cv::CAP_PROP_CONVERT_RGB, 0);` not.
Log info.
<img width="691" alt="log" src="https://github.com/opencv/opencv/assets/16932438/236e3b26-f5b2-447a-b202-bcd607c71af6">
We can also observe that we get the correct channels in the while loop. This is because:
ca0bd70cde/modules/videoio/src/cap_v4l.cpp (L2309-L2310)
reinitialize the `frame`.
2023-09-07 15:47:00 +03:00
..
cmake cmake: fix V4L config verification conflict with OBSENSOR 2023-03-19 10:58:47 +03:00
doc Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2021-11-20 05:13:50 +00:00
include/opencv2 Merge pull request #24012 from cudawarpedЖvideocapture_raw_read 2023-08-11 11:28:57 +03:00
misc Merge pull request #22939 from stopmosk:21826-python-bindings-for-videocapturewaitany 2022-12-14 22:15:02 +03:00
perf Merge pull request #15100 from Volskig:cam_multiplexing_function_v 2019-11-15 19:42:12 +03:00
src Merge pull request #24180 from MambaWong:4.x 2023-09-07 15:47:00 +03:00
test Merge pull request #24142 from beanjoy:4.x 2023-09-07 13:06:39 +03:00
CMakeLists.txt dnn(tflite): add 3rdparty flatbuffers with pre-generated schema 2023-02-21 16:06:19 +00:00