- 今日在对接大力ir红外sensor时,需要对前半部分YUV422的伪彩图像数据进行RGB24转换,源码可以实现转RGB24或者BGR24,部分函数可以删除掉,只关注重点转换函数即可
1. 实现源码
#ifndef __YUY2_FRAME_PROCESS_H__
#define __YUY2_FRAME_PROCESS_H__
#include "OLeiIrFrameDef.h"
#include "Stream/GpIrFrameProcess.h"
class CYuy2FrameProcess : public CGpIrFrameProcess
{
public:
CYuy2FrameProcess();
virtual ~CYuy2FrameProcess();
INT32 yuy2ToRgb24Convert(unsigned char* pSrc, unsigned char* pDst, int nImageWidth, int nImageHeight);
INT32 yuy2ToBgr24Convert(unsigned char* pSrc, unsigned char* pDst, int nImageWidth, int nImageHeight);
public:
virtual INT32 ProcessFrame(void* pData = NULL);
};
#endif
#include "Yuy2FrameProcess.h"
#include "Base/Thread/GpFrameProcessThread.h"
#include "Stream/GpFrameProcessCenter.h"
#include "Stream/Gpts/Yuy2FrameDef.h"
CYuy2FrameProcess::CYuy2FrameProcess()
{
LOGMSG("CYuy2FrameProcess::CYuy2FrameProcess");
TimePoint nTotalCostTm = currentTime();
this->setType(FrameProcessType_Yuv420);
LOGMSG("CYuy2FrameProcess::CYuy2FrameProcess is suc... nTotalCostTm=[%u]", (currentTime() - nTotalCostTm).count());
}
CYuy2FrameProcess::~CYuy2FrameProcess()
{
LOGMSG("CYuy2FrameProcess::~CYuy2FrameProcess");
TimePoint nTotalCostTm = currentTime();
this->releaseFrameProcThread();
LOGMSG("CYuy2FrameProcess::~CYuy2FrameProcess is suc... nTotalCostTm=[%llu]", (currentTime() - nTotalCostTm).count());
}
INT32 CYuy2FrameProcess::ProcessFrame(void *pData)
{
CGpFrameProcessThread* pThread = static_cast<CGpFrameProcessThread*>(pData);
CHECKI(pThread);
CHECKF(m_pFrameProcessCenter);
CGpFrame* pFrame = this->takeFirst();
if (!pFrame || pFrame->isEmpty())
{
msSleep(10);
return ReturnCode_Empty;
}
GpFrameType frameType = pFrame->getFrameType();
CHECKI(frameType == FRAME_TYPE_EXT_IR);
int nConvertFormat = CONVERT_FORMAT_RGB24;
int nRgb24Size = pFrame->getWidth() * pFrame->getHeight() * 3;
CGpFrame* pRgb24Frame = new CGpFrame(nRgb24Size);
if (pRgb24Frame == NULL)
{
LOGERROR("CYuy2FrameProcess::ProcessFrame new CGpFrame pRgb24Frame is NULL");
goto delete_frame;
}
pRgb24Frame->setBlockId(pFrame->getBlockId());
pRgb24Frame->setNetCode(pFrame->getNetCode());
pRgb24Frame->setCompressType(DATA_COMPRESS_RAW);
pRgb24Frame->setFrameType(FRAME_TYPE_RGB24);
pRgb24Frame->setWidth(pFrame->getWidth());
pRgb24Frame->setHeight(pFrame->getHeight());
pRgb24Frame->setChannelIndex(pFrame->getChannelIndex());
pRgb24Frame->setFrameCount(pFrame->getFrameCount());
pRgb24Frame->setTimestamp(pFrame->getTimestamp());
if (nConvertFormat == CONVERT_FORMAT_RGB24)
{
this->yuy2ToRgb24Convert((unsigned char*)pFrame->getData(), (unsigned char*)pRgb24Frame->getData(), pFrame->getWidth(), pFrame->getHeight());
}
else if (nConvertFormat == CONVERT_FORMAT_BGR24)
{
this->yuy2ToRgb24Convert((unsigned char*)pFrame->getData(), (unsigned char*)pRgb24Frame->getData(), pFrame->getWidth(), pFrame->getHeight());
}
else
{
LOGERROR("CYuy2FrameProcess::yuy2ToRgb24Convert nConvertFormat is error... nConvertFormat=[%d]", nConvertFormat);
goto delete_frame;
}
CGpFrameProcessCenter* pFrameProcessCenter = dynamic_cast<CGpFrameProcessCenter*>(this->getFrameProcessCenter());
if (pFrameProcessCenter == NULL)
{
LOGERROR("CYuy2FrameProcess::ProcessFrame pFrameProcessCenter is NULL");
goto delete_frame;
}
pFrameProcessCenter->outputFrame(pRgb24Frame);
delete_frame:
SAFE_DELETE(pFrame);
SAFE_DELETE(pRgb24Frame);
return ReturnCode_Success;
}
INT32 CYuy2FrameProcess::yuy2ToRgb24Convert(unsigned char* pSrc, unsigned char* pDst, int nImageWidth, int nImageHeight)
{
CHECKI(pSrc);
CHECKI(pDst);
CHECKI(nImageWidth > 0);
CHECKI(nImageHeight > 0);
unsigned char* pYuyvData = pSrc;
int z = 0;
int i = 0;
int j = 0;
for (i = 0; i < nImageHeight; i++)
{
for (j = 0; j < nImageWidth; j++)
{
int r, g, b;
int y, u, v;
if (!z)
{
y = pYuyvData[0] << 8;
}
else
{
y = pYuyvData[2] << 8;
}
u = pYuyvData[1] - 128;
v = pYuyvData[3] - 128;
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
r = (r > 255) ? 255 : ((r < 0) ? 0 : r);
g = (g > 255) ? 255 : ((g < 0) ? 0 : g);
b = (b > 255) ? 255 : ((b < 0) ? 0 : b);
*pDst++ = r;
*pDst++ = g;
*pDst++ = b;
if (z++)
{
z = 0;
pYuyvData += 4;
}
}
}
return ReturnCode_Success;
}
INT32 CYuy2FrameProcess::yuy2ToBgr24Convert(unsigned char* pSrc, unsigned char* pDst, int nImageWidth, int nImageHeight)
{
CHECKI(pSrc);
CHECKI(pDst);
CHECKI(nImageWidth > 0);
CHECKI(nImageHeight > 0);
unsigned char* pYuyvData = pSrc;
int z = 0;
int i = 0;
int j = 0;
for (i = 0; i < nImageHeight; i++)
{
for (j = 0; j < nImageWidth; j++)
{
int r, g, b;
int y, u, v;
if (!z)
{
y = pYuyvData[0] << 8;
}
else
{
y = pYuyvData[2] << 8;
}
u = pYuyvData[1] - 128;
v = pYuyvData[3] - 128;
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
r = (r > 255) ? 255 : ((r < 0) ? 0 : r);
g = (g > 255) ? 255 : ((g < 0) ? 0 : g);
b = (b > 255) ? 255 : ((b < 0) ? 0 : b);
*pDst++ = b;
*pDst++ = g;
*pDst++ = r;
if (z++)
{
z = 0;
pYuyvData += 4;
}
}
}
return ReturnCode_Success;
}
2. 测试文件
- 执行程序生产2个test_rgb24.bin和test_bgr24.bin文件,使用软件平台离线工具播放显示正确无误;