c++ - uint8_t 缓冲区到 cv::Mat 转换导致图像失真
问题描述
我有一个 Mipi 相机,它可以捕获帧并将它们存储到您可以在下面看到的结构缓冲区中。存储帧后,我想将其转换为 cv::Mat,问题是 Mat 最终看起来像第一张照片。
var buf.index 只是 V4L2 API 的一部分,有助于了解我正在使用哪个缓冲区。
//The structure where the data is stored
struct buffer{
void *start;
size_t length;
};
struct buffer *buffers;
//buffer->mat
cv::Mat im = cv::Mat(cv::Size(width, height), CV_8UC3, ((uint8_t*)buffers[buf.index].start));
起初我认为数据可能已损坏,但使用 lodepng 存储图像会产生没有任何失真的漂亮图像。
unsigned char* out_buf = (unsigned char*)malloc( width * height * 3);
for(int pix = 0; pix < width*height; ++pix) {
memcpy(out_buf + pix*3, ((uint8_t*)buffers[buf.index].start)+4*pix+1, 3);
}
lodepng_encode24_file(filename, out_buf, width, height);
我敢打赌这真的很愚蠢。
解决方案
您发布的图片具有奇怪的彩色像素,并且图案看起来比每像素 24 位的信息更多。
检查数据后,V4L 似乎为每个像素提供了四个字节,第一个字节始终为 0xFF(我们称之为 X)。此外,通道顺序似乎是 XRGB。
创建一个 cv::Mat8UC4
用于包含数据。
要在 OpenCV 中使用图片,您需要 BGR 命令。cv::split
将接收到的数据放入其四个颜色平面中,即 X、R、G、B。用于cv::merge
将 B、G、R 平面重新组装成 OpenCV 可以处理的图片,或重新组装成 R、G、B 以创建用于其他目的的 Mat(您似乎使用的其他库)。
推荐阅读
- javascript - 无法阅读其他部分
- javascript - 我将如何通过 php get 请求实现分页
- oauth - 如何解决 Netsuite Restlets 中的 400 bad request 错误?
- jmeter - Jmeter 与 UI 和数据库的交互同时插入
- android - 如何在反应原生中使用高程在android中插入盒子阴影?
- angular - ng-packagr 无法将 Angular 包发布到 npm 或如何修复 Angular Valunerablities
- javascript - 破碎的 apexcharts 图例(vue-apexcharts)
- asp.net - Azure Redis - 当模式=自定义时如何在 ASP.NET 应用程序中模拟 session_end 事件?
- c# - 我怎样才能把这个 onpaint 方法放在点击功能上?C#
- c# - 我可以为“valuetype”的 getter 和 setter 设置不同的返回类型吗?特性?