#pragma execution_character_set("utf-8") #include "CameraControl.h" #include CameraControl::CameraControl() { m_calib1 = ILCalibNPointsPtr(__uuidof(LCalibNPoints)); m_calib1->FixImageMode = LPVFixImageMode::LPVFixImageUndistortAndUntilt; m_calib2 = ILCalibNPointsPtr(__uuidof(LCalibNPoints)); m_calib2->FixImageMode = LPVFixImageMode::LPVFixImageUndistortAndUntilt; qRegisterMetaType >("QVector"); 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 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& 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::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::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::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::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::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::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 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; } }