mirror of
https://github.com/opencv/opencv.git
synced 2024-11-27 20:50:25 +08:00
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`.
This commit is contained in:
parent
d0de575aef
commit
e8f94182f5
@ -2155,6 +2155,7 @@ bool CvCaptureCAM_V4L::setProperty( int property_id, double _value )
|
||||
}else{
|
||||
convert_rgb = false;
|
||||
releaseFrame();
|
||||
v4l2_create_frame();
|
||||
return true;
|
||||
}
|
||||
case cv::CAP_PROP_FOURCC:
|
||||
|
Loading…
Reference in New Issue
Block a user