Ниже приведен процесс преобразования предоставленных YUV-файлов в RGB-изображение.
- Чтение двоичных файлов Y, U и V в байтовые буферы
- Создание объекта OpenCV Mat из созданных буферов.
- Изменение размера U и V Mats до размера Y.
- Объединить Y и изменить размер U и V.
- Конвертировать из YUV в BGR
Имейте в виду , что шаг изменения размера - это просто оптимизированный способ повторения значений U и V. Это справедливо только в случае, когда Y имеет двойное разрешение U и V в обоих измерениях. Этот подход должен быть недопустимым для изображений произвольного размера (не проверено).
Вот код для вышеупомянутого процесса.
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
std::vector<unsigned char> readBytesFromFile(const char* filename)
{
std::vector<unsigned char> result;
FILE* f = fopen(filename, "rb");
fseek(f, 0, SEEK_END); // Jump to the end of the file
long length = ftell(f); // Get the current byte offset in the file
rewind(f); // Jump back to the beginning of the file
result.resize(length);
char* ptr = reinterpret_cast<char*>(&(result[0]));
fread(ptr, length, 1, f); // Read in the entire file
fclose(f); // Close the file
return result;
}
int main(int argc, char** argv)
{
cv::Size actual_size(1920, 1080);
cv::Size half_size(960, 540);
//Read y, u and v in bytes arrays
auto y_buffer = readBytesFromFile("ypixel.bin");
auto u_buffer = readBytesFromFile("upixel.bin");
auto v_buffer = readBytesFromFile("vpixel.bin");
cv::Mat y(actual_size, CV_8UC1, y_buffer.data());
cv::Mat u(half_size, CV_8UC1, u_buffer.data());
cv::Mat v(half_size, CV_8UC1, v_buffer.data());
cv::Mat u_resized, v_resized;
cv::resize(u, u_resized, actual_size, 0, 0, cv::INTER_NEAREST); //repeat u values 4 times
cv::resize(v, v_resized, actual_size, 0, 0, cv::INTER_NEAREST); //repeat v values 4 times
cv::Mat yuv;
std::vector<cv::Mat> yuv_channels = { y, u_resized, v_resized };
cv::merge(yuv_channels, yuv);
cv::Mat bgr;
cv::cvtColor(yuv, bgr, cv::COLOR_YUV2BGR);
cv::imwrite("bgr.jpg", bgr);
return 0;
}
Скомпилировано и протестировано с помощью следующей команды:
g ++ -o yuv2rgb -std = c ++ 11 yuv2rgb.cpp -L / usr / local / lib -lopencv_core
-lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc
Следующее выходное изображение генерируется путем выполнения вышеуказанного кода: