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

651 lines
16 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma execution_character_set("utf-8")
#include "CameraControl.h"
#include <QDebug>
CameraControl::CameraControl()
{
m_calib1 = ILCalibNPointsPtr(__uuidof(LCalibNPoints));
m_calib1->FixImageMode = LPVFixImageMode::LPVFixImageUndistortAndUntilt;
m_calib2 = ILCalibNPointsPtr(__uuidof(LCalibNPoints));
m_calib2->FixImageMode = LPVFixImageMode::LPVFixImageUndistortAndUntilt;
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() <<"[QJsonDocument]: "<< 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;
case 210:
cameraType = CameraType::LXTof;
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.location = deviceObj.value("location").toInt();
m_cameraStockLocation.insert(cameraInfo.serialNumber, cameraInfo.location);
if (deviceObj.contains("calib_file"))
{
cameraInfo.calibFile = deviceObj.value("calib_file").toString();
if (cameraInfo.location == 1)
{
m_calib1->Load(cameraInfo.calibFile.toStdString().c_str());
}
else
{
m_calib2->Load(cameraInfo.calibFile.toStdString().c_str());
}
}
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_mapSNIndex.keys();
for each (const QString& serialNumber in serialNumberList)
{
if (!openCamera(serialNumber))
{
qWarning() << "Open camera: " << serialNumber << " failed";
continue;
}
else
{
qDebug() << "Open camera: " << serialNumber << " successed";
if (!startCamera(serialNumber))
{
qWarning() << "Start camera: " << serialNumber << " failed";
continue;
}
else
{
qDebug() << "Start camera: " << serialNumber << " successed";
if (!setSoftwareTrigger(serialNumber))
{
qWarning() << "Set camera: " << serialNumber << " software trigger failed";
}
else
{
qDebug() << "Set camera: " << serialNumber << " software trigger successed";
}
}
}
}
}
return true;
}
bool CameraControl::loadCamera(const QList<CameraInfo>& cameraInfoList)
{
bool flag = false;
for each (Camera* pCamera in m_vecPCamera)
{
DELETE_POINTER(pCamera);
}
m_vecPCamera.clear();
m_mapSNIndex.clear();
for each(CameraInfo cameraInfo in cameraInfoList)
{
qDebug() << "serialNumber[" << cameraInfo.serialNumber << "]:" << cameraInfo.cameraType;
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;
flag = true;
}
else
{
qWarning() << "SerialNumber: " << serialNumber << " init failed";
DELETE_POINTER(pHikCamera);
//flag = false;
}
}
else if (cameraType == CameraType::LXTof)
{
Camera* pLXCamera = new LXCamera();
if (pLXCamera->initCamera(serialNumber))
{
m_vecPCamera.push_back(pLXCamera);
m_mapSNIndex[serialNumber] = m_vecPCamera.size() - 1;
flag = true;
}
else
{
qWarning() << "SerialNumber: " << serialNumber << " init failed";
DELETE_POINTER(pLXCamera);
//flag = false;
}
}
}
qDebug() << "m_vecPCamera size: " << m_vecPCamera.size();
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);
}
bool CameraControl::capture(const QString& serialNumber, cv::Mat& img, cv::Mat& img3D, int exposure)
{
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();
m_vecPCamera[index]->setExposure(exposure);
m_vecPCamera[index]->takeAPic(img, img3D);
if (img.empty())
{
qWarning() << serialNumber << " capture empty";
}
return true;
}
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,int location, int floor)
{
QStringList serialNumList;
switch (cameraLocation)
{
case eCameraLocation::emTop:
m_eCameraLocation = emTop;
#if IMAGEDRAWING == LPV
for (auto iter = m_mapSerialNumberIdTop.begin(); iter != m_mapSerialNumberIdTop.end(); iter++)
{
if (m_cameraStockLocation[iter.key()] == location)
{
serialNumList << iter.key();
}
}
#elif IMAGEDRAWING == OPENCV
serialNumList = m_mapSerialNumberIdTop.keys();
#endif
break;
case eCameraLocation::emSide:
m_eCameraLocation = emSide;
#if IMAGEDRAWING == LPV
for (auto iter = m_mapSerialNumberIdSide.begin(); iter != m_mapSerialNumberIdSide.end(); iter++)
{
if (m_cameraStockLocation[iter.key()] == location)
{
serialNumList << iter.key();
}
}
#elif IMAGEDRAWING == OPENCV
serialNumList = m_mapSerialNumberIdSide.keys();
#endif // IMAGEDRAWING == LPV
break;
default:
break;
}
if (serialNumList.length() != 0)
{
qInfo() << "Captured SerialNumList = " << serialNumList;
capture(serialNumList, location, floor);
}
}
void CameraControl::capture(const QStringList& serialNumberList, int location, int floor)
{
int len = serialNumberList.length();
//qDebug() << "start capture, length: " << len;
QVector<ImageInfo> vecImageInfo;
for (int i = 0; i < len; ++i)
{
QString serialNumber = serialNumberList.at(i);
if (!m_mapSNIndex.contains(serialNumber))
{
qWarning() << "m_vecPCamera does not have camera: " << serialNumber;
continue;
}
ImageInfo imgInfo;
FileInfo saveImgInfo;
getSaveImgNameInfo(serialNumber, saveImgInfo);
imgInfo.saveImgInfo = saveImgInfo;
int id = 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;
}
////现在1和2巷道都是用的下三层1-3层曝光值250000ms/增益20
////中三层4-6层曝光值150000ms/增益20
////上三层7-9层曝光值50000ms/增益20
//if (floor!=0)
//{
// int exposure = 0;
// double gain = 0;
// if (floor >= 1 && floor <= 3)
// {
// exposure = 250000;
// }
// else if (floor >= 7 && floor <= 9)
// {
// exposure = 50000;
// }
// else
// {
// exposure = 150000;
// }
//}
if (!capture(serialNumber, imgInfo.image, imgInfo.image3D, floor))
{
vecImageInfo.push_back(imgInfo);
continue;
}
flipImg(imgInfo.image, imgInfo.image, rotationAngle);
imgInfo.cameraSn = serialNumber;
// 2D相机操作
if (imgInfo.imageOrigin == nullptr)
{
imgInfo.imageOrigin = ILImagePtr(__uuidof(LImage));
imgInfo.imageFixed = ILImagePtr(__uuidof(LImage));
}
imgInfo.imageOrigin->SetImageData(imgInfo.image.cols, imgInfo.image.rows, (void*)imgInfo.image.data, imgInfo.image.step, 0);
//if (serialNumber == "00787720450")
//{
// imgInfo.imageOrigin->Load("C:/Users/LENOVO/Downloads/0108/310102.bmp");
//}
//else if (serialNumber == "00J49540865")
//{
// imgInfo.imageOrigin->Load("C:/Users/LENOVO/Downloads/0108/320111.bmp");
//}
//else
//{
// imgInfo.imageOrigin->SetImageData(imgInfo.image.cols, imgInfo.image.rows, (void*)imgInfo.image.data, imgInfo.image.step, 0);
//}
if (imgInfo.image3D.empty()) //表面用的是2D相机
{
imgInfo.bIs2D = true;
if (location == 1 && m_calib1->IsCalibrated())
{
m_calib1->FixImage(imgInfo.imageOrigin, imgInfo.imageFixed);
}
else if (location == 2 && m_calib2->IsCalibrated())
{
m_calib2->FixImage(imgInfo.imageOrigin, imgInfo.imageFixed);
}
}
else
{
imgInfo.bIs2D = false;
}
vecImageInfo.push_back(imgInfo);
}
emit sgCapturedImage(vecImageInfo, m_eCameraLocation);
}
void CameraControl::flipImg(const cv::Mat& imgSrc, cv::Mat& imgDst, int rotationAngle)
{
if (imgSrc.empty())
{
qWarning() << "imgSrc is empty";
return;
}
switch (rotationAngle)
{
case 90:
cv::transpose(imgSrc, imgDst);
cv::flip(imgDst, imgDst, 1);
qDebug() << " 旋转90度";
break;
case 180:
cv::flip(imgSrc, imgDst, -1);
qDebug() << " 旋转180度";
break;
case 270:
cv::transpose(imgSrc, imgDst);
cv::flip(imgDst, imgDst, 0);
qDebug() << " 旋转270度";
break;
default:
imgDst = imgSrc;
qDebug() << " 不旋转";
break;
}
}