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: https://github.com/opencv/opencv/blob/ca0bd70cde431b1dd211254011dd9bcf965f582f/modules/videoio/src/cap_v4l.cpp#L2309-L2310 reinitialize the `frame`.
Showing
想要评论请 注册 或 登录