如果是把YUV灰度图(只有Y分量)转化为Mat
cv::Mat cv_img;
cv::Mat cv_yuv(height, width, CV_8UC1, pFrame);//pFrame为YUV数据地址
cv_img = cv::Mat(height, width, CV_LOAD_IMAGE_COLOR);
cv::cvtColor(cv_yuv, cv_img, COLOR_GRAY2BGR);
如果是把YUV彩色图转化为Mat
cv::Mat cv_img;
cv::Mat cv_yuv(height + height/2, width, CV_8UC1, pFrame);//pFrame为YUV数据地址,另外这里就是用 CV_8UC1非 CV_8UC3.
cv_img = cv::Mat(height, width, CV_8UC3);
cv::cvtColor(cv_yuv, cv_img, COLOR_YUV2BGR_I420);
另外,如果想jpg转成yuv nv12没有opencv直接可以实现,要用下面的代码
您好!我很抱歉给您带来困扰。我之前的回答中提到的 cv::COLOR_BGR2YUV_NV12
常量在 OpenCV 库中并不存在。正确的常量应该是 cv::COLOR_YUV2BGR_NV12
或 cv::COLOR_YUV2RGB_NV12
,它们分别用于将 NV12 格式的 YUV 图像转换为 BGR 或 RGB 图像。
如果您想将 JPG 图片转换为 NV12 格式的 YUV 图像,您可以先使用 cv::cvtColor
函数将 JPG 图片转换为 YUV 图像,然后再手动将其转换为 NV12 格式。下面是一个简单的示例代码,它演示了如何读取 JPG 图片并将其转换为 NV12 格式的 YUV 图像:
//读取jpg图片,模拟一个yuv输入数据。
cv::Mat cv_img = cv::imread(argv[2], 3);
// 获取图像的宽度和高度
int width = cv_img.cols;
int height = cv_img.rows;
cv::Mat yuvImage;
//cv::cvtColor(cv_img, yuvImage, cv::COLOR_BGR2YUV_I420);
cv::cvtColor(cv_img, yuvImage, cv::COLOR_BGR2YUV);
// 将 YUV 图像分离成 Y、U 和 V 三个通道
std::vector<cv::Mat> yuvChannels(3);
cv::split(yuvImage, yuvChannels);
cv::Mat yChannel = yuvChannels[0];
cv::Mat uChannel = yuvChannels[1];
cv::Mat vChannel = yuvChannels[2];
// 缩小 U 和 V 通道的图像
cv::resize(uChannel, uChannel, cv::Size(), 0.5, 0.5);
cv::resize(vChannel, vChannel, cv::Size(), 0.5, 0.5);
// 创建 NV12 图像
cv::Mat nv12Image(height * 3 / 2, width, CV_8UC1);
yChannel.copyTo(nv12Image(cv::Rect(0, 0, width, height)));
for (int i = 0; i < height / 2; i++) {
uchar* uvRow = nv12Image.ptr<uchar>(height + i);
uchar* uRow = uChannel.ptr<uchar>(i);
uchar* vRow = vChannel.ptr<uchar>(i);
for (int j = 0; j < width / 2; j++) {
uvRow[j * 2] = uRow[j];
uvRow[j * 2 + 1] = vRow[j];
}
}
以下代码是把yuv转成RGB的代码备份
//将输入的nv12图像转为rgba图像
void nv12_to_rgba(uint8_t* src_nv12, uint8_t* dst_rgba, int width, int height) {
if (width < 1 || height < 1 || src_nv12 == nullptr || dst_rgba == nullptr) {
return;
}
int frame_size = width * height;
uint8_t* y_plane = src_nv12;
uint8_t* uv_plane = src_nv12 + frame_size;
for (int j = 0; j < height; ++j) {
for (int i = 0; i < width; ++i) {
int y_index = j * width + i;
int uv_index = (j / 2) * width + (i & ~1);
uint8_t y = y_plane[y_index];
uint8_t u = uv_plane[uv_index];
uint8_t v = uv_plane[uv_index + 1];
int c = y - 16;
int d = u - 128;
int e = v - 128;
int r = (298 * c + 409 * e + 128) >> 8;
int g = (298 * c - 100 * d - 208 * e + 128) >> 8;
int b = (298 * c + 516 * d + 128) >> 8;
r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
int rgba_index = y_index * 4;
dst_rgba[rgba_index] = static_cast<uint8_t>(r);
dst_rgba[rgba_index + 1] = static_cast<uint8_t>(g);
dst_rgba[rgba_index + 2] = static_cast<uint8_t>(b);
dst_rgba[rgba_index + 3] = 255; // Alpha channel
}
}
}