SL100_FactoryTestTool/FactoryTestTool/SourceCode/Media/Media.cpp

300 lines
9.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Media.cpp
#include "Media.h"
// YUV 转换为 RGB 的辅助函数
void yuvToRgb(int y, int u, int v, int& r, int& g, int& b)
{
r = y + 1.402 * (v - 128);
g = y - 0.344136 * (u - 128) - 0.714136 * (v - 128);
b = y + 1.772 * (u - 128);
r = qBound(0, r, 255);
g = qBound(0, g, 255);
b = qBound(0, b, 255);
}
// 将 QImage 数据转换为 YUV422
QByteArray convertQImageToYUV422(const QImage& image)
{
int width = image.width();
int height = image.height();
QByteArray yuvData;
yuvData.resize(width * height * 2); // YUV422: 每个像素2字节
int index = 0;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; x += 2) {
QRgb pixel0 = image.pixel(x, y);
QRgb pixel1 = image.pixel(x + 1, y);
int r0 = qRed(pixel0);
int g0 = qGreen(pixel0);
int b0 = qBlue(pixel0);
int r1 = qRed(pixel1);
int g1 = qGreen(pixel1);
int b1 = qBlue(pixel1);
// 计算YUV值
int y0 = (0.299 * r0 + 0.587 * g0 + 0.114 * b0);
int u = (-0.169 * r0 - 0.331 * g0 + 0.5 * b0 + 128);
int y1 = (0.299 * r1 + 0.587 * g1 + 0.114 * b1);
int v = (0.5 * r0 - 0.419 * g0 - 0.081 * b0 + 128);
yuvData[index++] = static_cast<char>(qBound(0, y0, 255));
yuvData[index++] = static_cast<char>(qBound(0, u, 255));
yuvData[index++] = static_cast<char>(qBound(0, y1, 255));
yuvData[index++] = static_cast<char>(qBound(0, v, 255));
}
}
return yuvData;
}
// 将 QImage 数据转换为 YUV420
QByteArray convertQImageToYUV420(const QImage& image)
{
int width = image.width();
int height = image.height();
QByteArray yuvData;
int ySize = width * height;
int uvSize = (width / 2) * (height / 2);
yuvData.resize(ySize + 2 * uvSize); // Y 分量 + U 分量 + V 分量
int yIndex = 0;
int uIndex = ySize;
int vIndex = ySize + uvSize;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
QRgb pixel = image.pixel(x, y);
int r = qRed(pixel);
int g = qGreen(pixel);
int b = qBlue(pixel);
// 计算 YUV 值
int Y = qBound(0, static_cast<int>(0.299 * r + 0.587 * g + 0.114 * b), 255);
int U = qBound(0, static_cast<int>(-0.169 * r - 0.331 * g + 0.5 * b + 128), 255);
int V = qBound(0, static_cast<int>(0.5 * r - 0.419 * g - 0.081 * b + 128), 255);
// 填充 Y 分量
yuvData[yIndex++] = static_cast<char>(Y);
// 对 U 和 V 分量进行抽样
if (y % 2 == 0 && x % 2 == 0) {
yuvData[uIndex++] = static_cast<char>(U);
yuvData[vIndex++] = static_cast<char>(V);
}
}
}
return yuvData;
}
// 将 YUV422 数据转换为 QImage
QImage convertYUV422ToQImage(const QByteArray& yuv422Data, int width, int height)
{
QImage image(width, height, QImage::Format_RGB888);
const uchar* yuvPtr = reinterpret_cast<const uchar*>(yuv422Data.constData());
const uchar* yuvDataEnd = yuvPtr + yuv422Data.size();
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; x += 2) {
if (yuvPtr + 4 > yuvDataEnd) {
qWarning() << "YUV data access out of range!";
return image;
}
int y0 = yuvPtr[0];
int u = yuvPtr[1];
int y1 = yuvPtr[2];
int v = yuvPtr[3];
yuvPtr += 4;
int r0, g0, b0;
int r1, g1, b1;
yuvToRgb(y0, u, v, r0, g0, b0);
yuvToRgb(y1, u, v, r1, g1, b1);
image.setPixel(x, y, qRgb(r0, g0, b0));
image.setPixel(x + 1, y, qRgb(r1, g1, b1));
}
}
return image;
}
// 将 YUV420 数据转换为 QImage
QImage convertYUV420ToQImage(const QByteArray& yuv420Data, int width, int height)
{
QImage image(width, height, QImage::Format_RGB888);
const uchar* yData = reinterpret_cast<const uchar*>(yuv420Data.constData());
const uchar* uData = yData + width * height;
const uchar* vData = uData + (width * height) / 4;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int yValue = yData[y * width + x];
int uValue = uData[(y / 2) * (width / 2) + (x / 2)];
int vValue = vData[(y / 2) * (width / 2) + (x / 2)];
int r, g, b;
yuvToRgb(yValue, uValue, vValue, r, g, b);
image.setPixel(x, y, qRgb(r, g, b));
}
}
return image;
}
void DataHandler::showPic(QSize labelSize, int lens_n,
int width, int height, int format, const QByteArray* valData)
{
qDebug() << "lens_n = " << lens_n;
qDebug() << "format = " << format;
qDebug() << "width = " << width;
qDebug() << "height = " << height;
qDebug() << "yuvData size = " << valData->size();
QImage image;
if (format == YUV422) {
image = convertYUV422ToQImage(*valData, width, height);
}
else if (format == YUV420) {
image = convertYUV420ToQImage(*valData, width, height);
}
else {
qWarning() << "Unsupported image format! Please use YUV422 or YUV420 format";
return;
}
QTransform transform;
transform.rotate(90); // 可以调整旋转角度
QImage rotatedImage = image.transformed(transform);
QImage scaledImage = rotatedImage.scaled(labelSize, Qt::KeepAspectRatio);
QPixmap pixmap = QPixmap::fromImage(scaledImage);
if (lens_n == 0) {
//leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
emit updateLeftLensImage(pixmap);
}
else if (lens_n == 1) {
//rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
emit updateRightLensImage(pixmap);
}
else {
qWarning() << "Unsupported image lens!";
}
// 生成保存图片的目录
QString saveDirPath = QDir::currentPath() + "/frontBoardImage";
QDir saveDir(saveDirPath);
if (!saveDir.exists()) {
saveDir.mkpath(saveDirPath);
}
QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
QByteArray rotatedYuvData;
if (format == YUV422) {
rotatedYuvData = convertQImageToYUV422(rotatedImage);
}
else if (format == YUV420) {
rotatedYuvData = convertQImageToYUV420(rotatedImage);
}
QString yuvFileName = saveDirPath + "/" + currentTime + ".yuv";
QFile yuvFile(yuvFileName);
if (yuvFile.open(QIODevice::WriteOnly)) {
yuvFile.write(rotatedYuvData);
yuvFile.close();
qDebug() << "YUV image saved to" << yuvFileName;
}
else {
qWarning() << "Failed to save rotated YUV image to" << yuvFileName;
}
// 额外可以保存旋转后的图像为JPG或PNG格式
QString rotatedImageFileName = saveDirPath + "/" + currentTime + ".jpg";
rotatedImage.save(rotatedImageFileName, "JPG");
qDebug() << "JPG image saved to" << rotatedImageFileName;
}
void SerialDataHandler::showPic(QSize labelSize, int lens_n,
int width, int height, int format, const QByteArray* valData)
{
qDebug() << "lens_n = " << lens_n;
qDebug() << "format = " << format;
qDebug() << "width = " << width;
qDebug() << "height = " << height;
qDebug() << "yuvData size = " << valData->size();
QImage image;
if (format == YUV422) {
image = convertYUV422ToQImage(*valData, width, height);
}
else if (format == YUV420) {
image = convertYUV420ToQImage(*valData, width, height);
}
else {
qWarning() << "Unsupported image format! Please use YUV422 or YUV420 format";
return;
}
QTransform transform;
transform.rotate(270); // 可以调整旋转角度
QImage rotatedImage = image.transformed(transform);
QImage scaledImage = rotatedImage.scaled(labelSize, Qt::KeepAspectRatio);
QPixmap pixmap = QPixmap::fromImage(scaledImage);
if (lens_n == 0) {
//leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
emit updateLeftLensImage(pixmap);
}
else if (lens_n == 1) {
//rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
emit updateRightLensImage(pixmap);
}
else {
qWarning() << "Unsupported image lens!";
}
// 生成保存图片的目录
QString saveDirPath = QDir::currentPath() + "/frontBoardImage";
QDir saveDir(saveDirPath);
if (!saveDir.exists()) {
saveDir.mkpath(saveDirPath);
}
QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
QByteArray rotatedYuvData;
if (format == YUV422) {
rotatedYuvData = convertQImageToYUV422(rotatedImage);
}
else if (format == YUV420) {
rotatedYuvData = convertQImageToYUV420(rotatedImage);
}
QString len_num = "";
if (lens_n == 0)
len_num = "left";
else
len_num = "right";
QString yuvFileName = saveDirPath + "/" + len_num + "_" + currentTime + ".yuv";
QFile yuvFile(yuvFileName);
if (yuvFile.open(QIODevice::WriteOnly)) {
yuvFile.write(rotatedYuvData);
yuvFile.close();
qDebug() << "YUV image saved to" << yuvFileName;
}
else {
qWarning() << "Failed to save rotated YUV image to" << yuvFileName;
}
// 额外可以保存旋转后的图像为JPG或PNG格式
QString rotatedImageFileName = saveDirPath + "/" + len_num + "_" + currentTime + ".jpg";
rotatedImage.save(rotatedImageFileName, "JPG");
qDebug() << "JPG image saved to" << rotatedImageFileName;
}