该博客可以解决如下两个问题:
1、将mjpg格式数据转化成opencv Mat格式
2、v4l2_buffer 格式获取的mjpg格式数据转换成Mat格式。
要将 MJPEG 格式的数据转换为 OpenCV 的 Mat 格式,您可以使用 imdecode 函数。imdecode 函数可以将图像数据解码为 Mat 对象。以下是一个示例代码,演示了如何将 MJPEG 格式的数据转换为 Mat 格式:
#include <opencv2/opencv.hpp>
#include <vector>
// 假设 mjpeg_data 是存储 MJPEG 数据的字节数组
// 假设 mjpeg_data_size 是 MJPEG 数据的大小
// 将 MJPEG 数据转换为 Mat
std::vector<uchar> mjpeg_vec(mjpeg_data, mjpeg_data + mjpeg_data_size);
cv::Mat frame = cv::imdecode(mjpeg_vec, cv::IMREAD_COLOR);
// 检查是否成功解码
if (frame.empty()) {
// 解码失败
std::cout << "Failed to decode MJPEG data." << std::endl;
} else {
// 解码成功,可以对图像进行处理或显示
cv::imshow("MJPEG", frame);
cv::waitKey(0);
}
在上述代码中,我们首先将 MJPEG 数据存储在 std::vector 类型的容器 mjpeg_vec 中。然后,我们使用 imdecode 函数将 mjpeg_vec 中的数据解码为 Mat 对象。cv::IMREAD_COLOR 参数指定解码后的图像类型为彩色图像。
请注意,imdecode 函数返回的 Mat 对象可能为空(empty),这表示解码失败。因此,我们在代码中进行了空检查。如果解码成功,则可以对图像进行进一步处理或显示。
我自己的代码,是通过如下方式转换的:
struct v4l2_buffer v4l2_process_buf;
v4l2_process_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2_process_buf.memory = V4L2_MEMORY_MMAP;
...
// 4、 循环采集图像
while (1)
{
res = ioctl(fd, VIDIOC_DQBUF, &v4l2_process_buf);
...
std::vector<uchar> mjpeg_vec((char *)frm_base[v4l2_process_buf.index], (char *)frm_base[v4l2_process_buf.index] + v4l2_process_buf.bytesused);
frame = cv::imdecode(mjpeg_vec, cv::IMREAD_COLOR);
// 检查是否成功解码
if (frame.empty())
{
// 解码失败
std::cout << "Failed to decode MJPEG data." << std::endl;
return EXIT_FAILURE;
}
else
{
cv::resize(frame, resizedImage, newSize);
cv::namedWindow("frame", 0);
cv::imshow("frame", resizedImage);
cv::waitKey(1);
}
转换成功: