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

488 lines
12 KiB
C++

#pragma execution_character_set("utf-8")
#include "CameraControl.h"
#include <QDebug>
CameraControl::CameraControl()
{
qRegisterMetaType<QVector<ImageInfo> >("QVector<ImageInfo>");
m_pobjThread = new QThread;
moveToThread(m_pobjThread);
connect(m_pobjThread, &QThread::started, this, &CameraControl::onOpen);
connect(m_pobjThread, &QThread::finished,
this, &QObject::deleteLater);
m_pobjThread->start();
}
CameraControl::~CameraControl()
{
if (m_pobjThread)
{
m_pobjThread->quit();
m_pobjThread->wait();
m_pobjThread = nullptr;
}
for each (Camera* pCamera in m_vecPCamera)
{
DELETE_POINTER(pCamera);
}
m_vecPCamera.clear();
}
Q_SLOT void CameraControl::onOpen()
{
QString filePath = QCoreApplication::applicationDirPath() + CAMERA_CONFIG;
if (readCameraConfig(filePath))
{
m_bCamerasInit = initCamera();
}
}
bool CameraControl::readCameraConfig(QString filePath)
{
m_mapIdCameraInfoSide.clear();
m_mapIdCameraInfoTop.clear();
m_mapSerialNumberIdSide.clear();
m_mapSerialNumberIdTop.clear();
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qWarning() << "打开文件失败!";
return false;
}
QByteArray arr = file.readAll();
file.close();
if (arr.isEmpty())
{
qWarning() << "内容为空";
return false;
}
QJsonParseError err;
QJsonDocument doc = QJsonDocument::fromJson(arr, &err);
if (doc.isEmpty())
{
qWarning() << err.errorString(); //打印失败信息
return false;
}
QJsonObject jsonObj = doc.object();
auto getCameraType = [](int type)-> CameraType
{
CameraType cameraType;
switch (type)
{
case 100:
cameraType = CameraType::Virtual;
break;
case 140:
cameraType = CameraType::Hik;
break;
case 190:
cameraType = CameraType::Basler;
break;
default:
break;
}
return cameraType;
};
QJsonObject topObj = jsonObj.value("top").toObject();
int topStartId, topEndId;
if (!topObj.isEmpty())
{
topStartId = topObj.value("startID").toInt();
topEndId = topObj.value("endID").toInt();
}
else
{
qWarning() << "top id error";
return false;
}
QJsonObject sideObj = jsonObj.value("side").toObject();
int sideStartId, sideEndId;
if (!sideObj.isEmpty())
{
sideStartId = sideObj.value("startID").toInt();
sideEndId = sideObj.value("endID").toInt();
}
else
{
qWarning() << "side id error";
return false;
}
QJsonObject devicesObj = jsonObj.value("devices").toObject();
if (!devicesObj.isEmpty()) {
QStringList devicesLabelList = devicesObj.keys();
for each (QString deviceLabel in devicesLabelList)
{
CameraInfo cameraInfo;
cameraInfo.cameraLabel = deviceLabel;
QStringList strList = deviceLabel.split(' ');
if (strList.length() != 2)
{
qWarning() << "Device label: " << deviceLabel << " syntax error!";
continue;
}
cameraInfo.modelName = strList.at(0);
cameraInfo.serialNumber = strList.at(1);
QJsonObject deviceObj = devicesObj.value(deviceLabel).toObject();
if (!deviceObj.isEmpty())
{
cameraInfo.cameraType = getCameraType(deviceObj.value("type").toInt());
cameraInfo.exposure = deviceObj.value("exposure").toDouble();
cameraInfo.imageHeight = deviceObj.value("height").toInt();
cameraInfo.imageWidth = deviceObj.value("width").toInt();
cameraInfo.saveImgSuffix = deviceObj.value("save_img_suffix").toString();
int id = deviceObj.value("id").toInt();
if (deviceObj.contains("rotation_angle"))
{
cameraInfo.rotationAngle = deviceObj.value("rotation_angle").toInt();
}
if (id >= topStartId && id <= topEndId)
{
m_mapIdCameraInfoTop[id] = cameraInfo;
m_mapSerialNumberIdTop[cameraInfo.serialNumber] = id;
}
else if (id >= sideStartId && id <= sideEndId)
{
m_mapIdCameraInfoSide[id] = cameraInfo;
m_mapSerialNumberIdSide[cameraInfo.serialNumber] = id;
}
}
}
}
return true;
}
bool CameraControl::initCamera()
{
QList<CameraInfo> cameraInfoList = m_mapIdCameraInfoSide.values();
cameraInfoList.append(m_mapIdCameraInfoTop.values());
if (!loadCamera(cameraInfoList))
{
qWarning() << "Load camera failed";
return false;
}
else {
QStringList serialNumberList = m_mapSerialNumberIdSide.keys();
serialNumberList.append(m_mapSerialNumberIdTop.keys());
if (!openCamera(serialNumberList))
{
qWarning() << "Open camera failed";
return false;
}
else {
if (!startCamera(serialNumberList))
{
qWarning() << "Start camera failed";
return false;
}
else {
if (!setSoftwareTrigger(serialNumberList))
{
qWarning() << "Set software trigger failed";
}
}
}
}
return true;
}
bool CameraControl::loadCamera(const QList<CameraInfo>& cameraInfoList)
{
bool flag = true;
for each (Camera* pCamera in m_vecPCamera)
{
DELETE_POINTER(pCamera);
}
m_vecPCamera.clear();
m_mapSNIndex.clear();
for each(CameraInfo cameraInfo in cameraInfoList)
{
QString serialNumber = cameraInfo.serialNumber;
CameraType cameraType = cameraInfo.cameraType;
if (cameraType == CameraType::Hik)
{
Camera* pHikCamera = new HikCamera();
if (pHikCamera->initCamera(serialNumber))
{
m_vecPCamera.push_back(pHikCamera);
m_mapSNIndex[serialNumber] = m_vecPCamera.size() - 1;
}
else
{
qWarning() << "SerialNumber: " << serialNumber << " init failed";
flag = true;
}
}
}
return flag;
}
bool CameraControl::openCamera(const QStringList& serialNumberList)
{
bool flag = true;
for each (QString serialNumber in serialNumberList)
{
if (!openCamera(serialNumber))
{
qWarning() << "Open " << serialNumber << "failed!";
flag = false;
}
else
{
qDebug() << "Open " << serialNumber << " successed";
}
}
return flag;
}
bool CameraControl::closeCamera(const QStringList& serialNumberList)
{
bool flag = true;
for each (QString serialNumber in serialNumberList)
{
if (!closeCamera(serialNumber))
{
qWarning() << "Close " << serialNumber << "failed!";
flag = false;
}
else
{
qDebug() << "Close " << serialNumber << " successed";
}
}
return flag;
}
bool CameraControl::startCamera(const QStringList& serialNumberList)
{
bool flag = true;
for each (QString serialNumber in serialNumberList)
{
if (!startCamera(serialNumber))
{
qWarning() << "Start " << serialNumber << "failed!";
flag = false;
}
else
{
qDebug() << "Start " << serialNumber << " successed";
}
}
return flag;
}
bool CameraControl::stopCamera(const QStringList& serialNumberList)
{
bool flag = true;
for each (QString serialNumber in serialNumberList)
{
if (!stopCamera(serialNumber))
{
qWarning() << "Stop " << serialNumber << "failed!";
flag = false;
}
else
{
qDebug() << "Stop " << serialNumber << " successed";
}
}
return flag;
}
bool CameraControl::setSoftwareTrigger(const QStringList& serialNumberList)
{
bool flag = true;
for each (QString serialNumber in serialNumberList)
{
if (!setSoftwareTrigger(serialNumber))
{
qWarning() << "Set " << serialNumber << " software trigger failed!";
flag = false;
}
else
{
qDebug() << "Set " << serialNumber << " software trigger successed";
}
}
return flag;
}
bool CameraControl::openCamera(const QString& serialNumber)
{
QMap<QString, int>::iterator iter = m_mapSNIndex.find(serialNumber);
if (iter == m_mapSNIndex.end())
{
qWarning() << "Do not find " << serialNumber;
return false;
}
int index = iter.value();
return m_vecPCamera[index]->openCamera();
}
bool CameraControl::closeCamera(const QString& serialNumber)
{
QMap<QString, int>::iterator iter = m_mapSNIndex.find(serialNumber);
if (iter == m_mapSNIndex.end())
{
qWarning() << "Do not find " << serialNumber;
return false;
}
int index = iter.value();
return m_vecPCamera[index]->closeCamera();
}
bool CameraControl::startCamera(const QString& serialNumber)
{
QMap<QString, int>::iterator iter = m_mapSNIndex.find(serialNumber);
if (iter == m_mapSNIndex.end())
{
qWarning() << "Do not find " << serialNumber;
return false;
}
int index = iter.value();
return m_vecPCamera[index]->startCamera();
}
bool CameraControl::stopCamera(const QString& serialNumber)
{
QMap<QString, int>::iterator iter = m_mapSNIndex.find(serialNumber);
if (iter == m_mapSNIndex.end())
{
qWarning() << "Do not find " << serialNumber;
return false;
}
int index = iter.value();
return m_vecPCamera[index]->stopCamera();
}
bool CameraControl::setSoftwareTrigger(const QString& serialNumber)
{
QMap<QString, int>::iterator iter = m_mapSNIndex.find(serialNumber);
if (iter == m_mapSNIndex.end())
{
qWarning() << "Do not find " << serialNumber;
return false;
}
int index = iter.value();
return m_vecPCamera[index]->setTriggerSource(SOFTWARE);
}
cv::Mat CameraControl::capture(const QString& serialNumber)
{
QMap<QString, int>::iterator iter = m_mapSNIndex.find(serialNumber);
if (iter == m_mapSNIndex.end())
{
qWarning() << "Do not find " << serialNumber;
return cv::Mat();
}
int index = iter.value();
cv::Mat imgMat;
m_vecPCamera[index]->takeAPic(imgMat);
if (imgMat.empty())
{
qWarning() << serialNumber << " capture empty";
}
return imgMat;
}
bool CameraControl::getSaveImgNameInfo(QString serialNumber, FileInfo& fileInfo)
{
QString imgSaveBaseName;
auto iter = m_mapSerialNumberIdSide.find(serialNumber);
if (iter == m_mapSerialNumberIdSide.end())
{
iter = m_mapSerialNumberIdTop.find(serialNumber);
if (iter != m_mapSerialNumberIdTop.end())
{
int id = iter.value();
QString suffix = m_mapIdCameraInfoTop.value(id).saveImgSuffix;
fileInfo.suffix = suffix;
fileInfo.strId = QString::number(id);
fileInfo.name = fileInfo.strId + suffix;
}
else
{
qWarning() << "Can not find " << serialNumber;
return false;
}
}
else
{
int id = iter.value();
QString suffix = m_mapIdCameraInfoSide.value(id).saveImgSuffix;
fileInfo.suffix = suffix;
fileInfo.strId = QString::number(id);
fileInfo.name = fileInfo.strId + suffix;
}
return true;
}
Q_SLOT void CameraControl::onCapture(int cameraLocation)
{
QStringList serialNumList;
switch (cameraLocation)
{
case eCameraLocation::emTop:
m_eCameraLocation = emTop;
serialNumList = m_mapSerialNumberIdTop.keys();
break;
case eCameraLocation::emSide:
m_eCameraLocation = emSide;
serialNumList = m_mapSerialNumberIdSide.keys();
break;
default:
break;
}
capture(serialNumList);
}
void CameraControl::capture(const QStringList& serialNumberList)
{
int len = serialNumberList.length();
qDebug() << "start capture, length: " << len;
QVector<ImageInfo> vecImageInfo(len);
for (int i = 0; i < len; ++i)
{
QString serialNumber = serialNumberList.at(i);
getSaveImgNameInfo(serialNumber, vecImageInfo[i].saveImgInfo);
int id = vecImageInfo.at(i).saveImgInfo.strId.toInt();
int rotationAngle = 0;
if (m_mapIdCameraInfoTop.contains(id))
{
rotationAngle = m_mapIdCameraInfoTop.value(id).rotationAngle;
}
else if (m_mapIdCameraInfoSide.contains(id))
{
rotationAngle = m_mapIdCameraInfoSide.value(id).rotationAngle;
}
flipImg(capture(serialNumber), vecImageInfo[i].image, rotationAngle);
//vecImageInfo[i].image = capture(serialNumber);
vecImageInfo[i].cameraSn = serialNumber;
}
emit sgCapturedImage(vecImageInfo, m_eCameraLocation);
}
void CameraControl::flipImg(const cv::Mat& imgSrc, cv::Mat& imgDst, int rotationAngle)
{
switch (rotationAngle)
{
case 90:
cv::transpose(imgSrc, imgDst);
cv::flip(imgDst, imgDst, 1);
qDebug() << " 旋转90度";
break;
case 180:
cv::flip(imgSrc, imgDst, 0);
qDebug() << " 旋转180度";
break;
case 270:
cv::transpose(imgSrc, imgDst);
cv::flip(imgDst, imgDst, 0);
qDebug() << " 旋转270度";
break;
default:
imgDst = imgSrc;
qDebug() << " 不旋转";
break;
}
}