You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
6.5 KiB

#include <memory>
#include "utils.h"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
SimTargetImage_Y16::SimTargetImage_Y16(int w, int h)
{
pSrc = new unsigned short[w * h];
Y8Mat = cv::Mat(h,w,CV_8UC1);
nImageWidth = w;
nImageHeight = h;
}
SimTargetImage_Y16::~SimTargetImage_Y16()
{
if (pSrc)
{
delete[]pSrc;
pSrc = nullptr;
}
}
void SimTargetImage_Y16::setBackGround(int gray, int std)
{
for (size_t i = 0; i < nImageHeight; i++)
{
for (size_t j = 0; j < nImageWidth; j++)
{
pSrc[i * nImageWidth + j] = rand() % std + gray;
}
}
}
void SimTargetImage_Y16::addTarget(int x, int y, int w, int h, int gray)
{
for (size_t i = y - h/2; i < y + h/2; i++)
{
for (size_t j = x - w/2; j < x+w/2; j++)
{
pSrc[i * nImageWidth + j] = gray;
}
}
}
unsigned short* SimTargetImage_Y16::getImageData()
{
return pSrc;
}
cv::Mat SimTargetImage_Y16::getMatRGB()
{
Map16BitTo8Bit(pSrc, nImageHeight * nImageWidth, Y8Mat.data);
cv::Mat rgb;
cv::cvtColor(Y8Mat,rgb,COLOR_GRAY2RGB);
return rgb.clone();
}
SimTargetImage::SimTargetImage(int w,int h)
{
m_BaseMat = cv::Mat(h,w,CV_8UC3);
m_CurMat = m_BaseMat.clone();
m_imgW = w;
m_imgH = h;
}
void SimTargetImage::update()
{
m_CurMat = m_BaseMat.clone();
// 绘制目标
for (int i = 0; i < m_targetList.size(); ++i)
{
Target* target = &m_targetList[i];
// 更新目标位置
target->updatePosition(m_imgW, m_imgH);
target->updateTexture();
drawObj(*target);
}
// 绘制遮挡
for (int i = 0; i < m_OccList.size(); ++i)
{
Target* target = &m_OccList[i];
// 绘制目标
drawOcc(*target);
}
}
void SimTargetImage::setBackGround(int gray, int std)
{
cv::Mat noise(m_BaseMat.size(), CV_8UC3);
cv::randn(noise, cv::Scalar::all(gray), cv::Scalar::all(std)); // 高斯噪声
m_BaseMat = noise;
m_CurMat = noise.clone();
}
void SimTargetImage::addTarget(Target t)
{
m_targetList.push_back(t);
}
void SimTargetImage::addOcc(Target t)
{
m_OccList.push_back(t);
}
cv::Mat SimTargetImage::getImageRGB()
{
return m_CurMat;
}
cv::Mat SimTargetImage::getImageY16()
{
cvtColor(m_CurMat,matY8,COLOR_BGR2GRAY);
matY8.convertTo(matY16,CV_16UC1);
return matY16*3+4000;
}
cv::Mat SimTargetImage::getImageY8()
{
cvtColor(m_CurMat,matY8,COLOR_BGR2GRAY);
return matY8;
}
cv::Mat SimTargetImage::getImageNV12()
{
matNV12 = cv::Mat(m_imgH*1.5, m_imgW, CV_8UC1);
cv::Mat matYUV_I420(m_imgH*1.5, m_imgW, CV_8UC1);
cvtColor(m_CurMat, matYUV_I420, COLOR_BGR2YUV_I420);
int nLenY = m_imgW * m_imgH;
int nLenU = nLenY / 4;
uchar* pNV12 = matNV12.data;
uchar* pUV = matNV12.data + nLenY;
uchar* pI420 = matYUV_I420.data;
memcpy(pNV12, pI420, nLenY);
for (int i = 0; i < nLenU; i++)
{
pUV[2 * i] = pI420[nLenY + i]; // U
pUV[2 * i + 1] = pI420[nLenY + nLenU + i]; // V
}
return matNV12;
}
Target* SimTargetImage::getTarget(int id)
{
if (m_targetList.size() > 0)
{
return &m_targetList[id];
}
else
{
return nullptr;
}
}
void SimTargetImage::drawObj(Target t)
{
if (t.useTexture)
{
// 设置叠加位置
int offsetX = t.x - t.width/2, offsetY = t.y - t.height/2;
cv::Rect roi(offsetX, offsetY, t.width, t.height);
// // 将前景叠加到背景,使用 Alpha 通道作为掩码
t.texture_cur.copyTo(m_CurMat(roi),t.alaph_cur);
return;
}
cv::Rect rect(t.x - t.width/2, t.y - t.height/2, t.width, t.height);
cv::rectangle(m_CurMat, rect, cv::Scalar(t.color), cv::FILLED);
}
void SimTargetImage::drawOcc(Target t)
{
cv::Rect rect(t.x - t.width/2, t.y - t.height/2, t.width, t.height);
cv::rectangle(m_CurMat, rect, cv::Scalar(t.color), cv::FILLED);
}
void Map16BitTo8Bit(unsigned short* psh16BitData, long lDataLen, unsigned char* pby8BitData)
{
if (psh16BitData == NULL || pby8BitData == NULL || lDataLen <= 0)
{
return;
}
//指向直方图的数据指针
int* pHist = new int[65536];
memset(pHist, 0, 65536 * sizeof(int));
int i = 0;
for (i = 0; i < lDataLen; i += 10)
{
pHist[psh16BitData[i]]++;
}
//设置阈值大小为: AreaSigma*图象大小/100
int nSigma = (int)(0.03 * lDataLen);
int nSum = 0;
int nMin = 0;
int nMax = 0;
//求映射的最大最小值
for (i = 0; i < 65536; i++)
{
nSum += pHist[i];
if (nSum >= nSigma)
{
nMin = i;
break;
}
}
nSum = 0;
for (i = 65535; i >= 0; i--)
{
nSum += pHist[i];
if (nSum >= nSigma)
{
nMax = i;
break;
}
}
//计算对比度亮度
float K = (float)(120.0 / (nMax - nMin + 1));
float C = (float)(-K * nMin);
//图像映射
for (i = 0; i < lDataLen; i++)
{
int nValue = (int)(K * psh16BitData[i] + C);
if (nValue < 0)
{
pby8BitData[i] = 0;
}
else if (nValue > 255)
{
pby8BitData[i] = 255;
}
else
{
pby8BitData[i] = nValue;
}
}
delete[] pHist;
}
void showArithInfo(cv::Mat src, ARIDLL_OUTPUT * stOutput)
{
auto detNum = stOutput->nAlarmObjCnts;
auto detObjs = stOutput->stAlarmObjs;
for (size_t i = 0; i < detNum; i++)
{
cv::Rect outRect;
outRect.width = MAX(15,int(detObjs[i].nObjW));
outRect.height= MAX(15,int(detObjs[i].nObjH));
outRect.x = detObjs[i].nX-outRect.width/2.0;
outRect.y = detObjs[i].nY-outRect.height/2.0;
cv::rectangle(src,outRect,cv::Scalar(255,0,0),2);
cv::putText(src,to_string(detObjs[i].nOutputID),cv::Point(outRect.x - 10,outRect.y),1,2,cv::Scalar(255,255,0));
}
auto trackerOut = stOutput->stTrackers[0];
cv::Rect outRect;
outRect.width = MAX(25,int(trackerOut.nObjW));
outRect.height= MAX(25,int(trackerOut.nObjH));
outRect.x = trackerOut.nX-outRect.width/2.0;
outRect.y = trackerOut.nY-outRect.height/2.0;
cv::rectangle(src,outRect,cv::Scalar(0,0,255),2);
char str[100];
sprintf(str,"%d,%d,%d,%d",int(trackerOut.nX),int(trackerOut.nY),int(trackerOut.nObjW),int(trackerOut.nObjH));
cv::putText(src,cv::String(str),cv::Point(outRect.x - 10,outRect.y),1,2,cv::Scalar(255,255,0));
}