diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/dao/FaceDataDao.cpp b/dao/FaceDataDao.cpp index 89a05da..7d1f873 100644 --- a/dao/FaceDataDao.cpp +++ b/dao/FaceDataDao.cpp @@ -30,21 +30,94 @@ result.append(item); } - LOG(TRACE) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); + LOG(DEBUG) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); return result; } QVariantMap FaceDataDao::findRecordById(QString id) { - QVariantMap item; - return item; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(DEBUG) << QString("根据id查询FACE_DATA表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); + return result; +} + +QVariantMap FaceDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(personId); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(TRACE) << QString("根据id查询FACE_DATA表的记录[personId=%1][%2]").arg(personId).arg(sql).toStdString(); + return result; } QVector FaceDataDao::findRecordsByProperty(QString properName, QVariant properValue) { + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM FACE_DATA WHERE %1 = '%2'"; + sql = sql.arg(properName).arg(properValue.toString()); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_code", query.value("face_code").toString()); + result.append(item); + } + + LOG(DEBUG) << QString("根据属性值查询FACE_DATA表的记录[%1][%2]").arg(count).arg(sql).toStdString(); return result; } @@ -89,10 +162,51 @@ bool FaceDataDao::edit(QVariantMap newObject, QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("face_code")){ + return false; + } + QString sql = QString("UPDATE FACE_DATA SET FACE_CODE = :faceCode WHERE ID = '%1'").arg(id); + query.prepare(sql); + query.bindValue(":faceCode", newObject.value("face_code")); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } bool FaceDataDao::dele(QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA WHERE ID = '%1'").arg(id); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/dao/FaceDataDao.cpp b/dao/FaceDataDao.cpp index 89a05da..7d1f873 100644 --- a/dao/FaceDataDao.cpp +++ b/dao/FaceDataDao.cpp @@ -30,21 +30,94 @@ result.append(item); } - LOG(TRACE) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); + LOG(DEBUG) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); return result; } QVariantMap FaceDataDao::findRecordById(QString id) { - QVariantMap item; - return item; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(DEBUG) << QString("根据id查询FACE_DATA表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); + return result; +} + +QVariantMap FaceDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(personId); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(TRACE) << QString("根据id查询FACE_DATA表的记录[personId=%1][%2]").arg(personId).arg(sql).toStdString(); + return result; } QVector FaceDataDao::findRecordsByProperty(QString properName, QVariant properValue) { + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM FACE_DATA WHERE %1 = '%2'"; + sql = sql.arg(properName).arg(properValue.toString()); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_code", query.value("face_code").toString()); + result.append(item); + } + + LOG(DEBUG) << QString("根据属性值查询FACE_DATA表的记录[%1][%2]").arg(count).arg(sql).toStdString(); return result; } @@ -89,10 +162,51 @@ bool FaceDataDao::edit(QVariantMap newObject, QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("face_code")){ + return false; + } + QString sql = QString("UPDATE FACE_DATA SET FACE_CODE = :faceCode WHERE ID = '%1'").arg(id); + query.prepare(sql); + query.bindValue(":faceCode", newObject.value("face_code")); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } bool FaceDataDao::dele(QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA WHERE ID = '%1'").arg(id); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } diff --git a/dao/FaceDataDao.h b/dao/FaceDataDao.h index 87fce40..6856a40 100644 --- a/dao/FaceDataDao.h +++ b/dao/FaceDataDao.h @@ -13,6 +13,7 @@ QVector findAllRecord(); QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); QVector findRecordsByProperty(QString properName, QVariant properValue); QString save(QVariantMap object); diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/dao/FaceDataDao.cpp b/dao/FaceDataDao.cpp index 89a05da..7d1f873 100644 --- a/dao/FaceDataDao.cpp +++ b/dao/FaceDataDao.cpp @@ -30,21 +30,94 @@ result.append(item); } - LOG(TRACE) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); + LOG(DEBUG) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); return result; } QVariantMap FaceDataDao::findRecordById(QString id) { - QVariantMap item; - return item; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(DEBUG) << QString("根据id查询FACE_DATA表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); + return result; +} + +QVariantMap FaceDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(personId); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(TRACE) << QString("根据id查询FACE_DATA表的记录[personId=%1][%2]").arg(personId).arg(sql).toStdString(); + return result; } QVector FaceDataDao::findRecordsByProperty(QString properName, QVariant properValue) { + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM FACE_DATA WHERE %1 = '%2'"; + sql = sql.arg(properName).arg(properValue.toString()); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_code", query.value("face_code").toString()); + result.append(item); + } + + LOG(DEBUG) << QString("根据属性值查询FACE_DATA表的记录[%1][%2]").arg(count).arg(sql).toStdString(); return result; } @@ -89,10 +162,51 @@ bool FaceDataDao::edit(QVariantMap newObject, QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("face_code")){ + return false; + } + QString sql = QString("UPDATE FACE_DATA SET FACE_CODE = :faceCode WHERE ID = '%1'").arg(id); + query.prepare(sql); + query.bindValue(":faceCode", newObject.value("face_code")); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } bool FaceDataDao::dele(QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA WHERE ID = '%1'").arg(id); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } diff --git a/dao/FaceDataDao.h b/dao/FaceDataDao.h index 87fce40..6856a40 100644 --- a/dao/FaceDataDao.h +++ b/dao/FaceDataDao.h @@ -13,6 +13,7 @@ QVector findAllRecord(); QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); QVector findRecordsByProperty(QString properName, QVariant properValue); QString save(QVariantMap object); diff --git a/dao/FaceDataImgDao.cpp b/dao/FaceDataImgDao.cpp index d863752..7f3704e 100644 --- a/dao/FaceDataImgDao.cpp +++ b/dao/FaceDataImgDao.cpp @@ -23,7 +23,9 @@ while (query.next()) { QVariantMap item; - item.insert("id", query.value("id").toULongLong()); + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_image", query.value("face_image").toString()); result.append(item); } @@ -46,20 +48,15 @@ // 返回结果 QVariantMap result; - // 获取结果集的大小 - query.last(); - int count = query.at() + 1; - - if (count >=1) + // 获取结果 + if (query.next()) { - query.first(); - result.insert("id", query.value("id").toString()); result.insert("person_id", query.value("person_id").toString()); result.insert("face_image", query.value("face_image").toString()); } - LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(count).arg(sql).toStdString(); + LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); return result; } @@ -166,12 +163,39 @@ { // 新建查询 QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + // UPDATE语句 if (!newObject.contains("face_image")){ - return true; + return false; } - QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = '%1'").arg(newObject.value("face_image").toString()); - sql.append(QString(" WHERE PERSON_ID = %1").arg(id)); + QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = :faceImage WHERE ID = '%1'").arg(id); + + query.prepare(sql); + query.bindValue(":faceImage", newObject.value("face_image")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + LOG(DEBUG) << sql.toStdString(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool FaceDataImgDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA_IMAGE WHERE ID = '%1'").arg(id); LOG(DEBUG) << sql.toStdString(); @@ -183,11 +207,7 @@ // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); + // 返回结果 return success; } - -bool FaceDataImgDao::dele(QString id) -{ - return false; -} diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/dao/FaceDataDao.cpp b/dao/FaceDataDao.cpp index 89a05da..7d1f873 100644 --- a/dao/FaceDataDao.cpp +++ b/dao/FaceDataDao.cpp @@ -30,21 +30,94 @@ result.append(item); } - LOG(TRACE) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); + LOG(DEBUG) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); return result; } QVariantMap FaceDataDao::findRecordById(QString id) { - QVariantMap item; - return item; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(DEBUG) << QString("根据id查询FACE_DATA表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); + return result; +} + +QVariantMap FaceDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(personId); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(TRACE) << QString("根据id查询FACE_DATA表的记录[personId=%1][%2]").arg(personId).arg(sql).toStdString(); + return result; } QVector FaceDataDao::findRecordsByProperty(QString properName, QVariant properValue) { + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM FACE_DATA WHERE %1 = '%2'"; + sql = sql.arg(properName).arg(properValue.toString()); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_code", query.value("face_code").toString()); + result.append(item); + } + + LOG(DEBUG) << QString("根据属性值查询FACE_DATA表的记录[%1][%2]").arg(count).arg(sql).toStdString(); return result; } @@ -89,10 +162,51 @@ bool FaceDataDao::edit(QVariantMap newObject, QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("face_code")){ + return false; + } + QString sql = QString("UPDATE FACE_DATA SET FACE_CODE = :faceCode WHERE ID = '%1'").arg(id); + query.prepare(sql); + query.bindValue(":faceCode", newObject.value("face_code")); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } bool FaceDataDao::dele(QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA WHERE ID = '%1'").arg(id); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } diff --git a/dao/FaceDataDao.h b/dao/FaceDataDao.h index 87fce40..6856a40 100644 --- a/dao/FaceDataDao.h +++ b/dao/FaceDataDao.h @@ -13,6 +13,7 @@ QVector findAllRecord(); QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); QVector findRecordsByProperty(QString properName, QVariant properValue); QString save(QVariantMap object); diff --git a/dao/FaceDataImgDao.cpp b/dao/FaceDataImgDao.cpp index d863752..7f3704e 100644 --- a/dao/FaceDataImgDao.cpp +++ b/dao/FaceDataImgDao.cpp @@ -23,7 +23,9 @@ while (query.next()) { QVariantMap item; - item.insert("id", query.value("id").toULongLong()); + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_image", query.value("face_image").toString()); result.append(item); } @@ -46,20 +48,15 @@ // 返回结果 QVariantMap result; - // 获取结果集的大小 - query.last(); - int count = query.at() + 1; - - if (count >=1) + // 获取结果 + if (query.next()) { - query.first(); - result.insert("id", query.value("id").toString()); result.insert("person_id", query.value("person_id").toString()); result.insert("face_image", query.value("face_image").toString()); } - LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(count).arg(sql).toStdString(); + LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); return result; } @@ -166,12 +163,39 @@ { // 新建查询 QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + // UPDATE语句 if (!newObject.contains("face_image")){ - return true; + return false; } - QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = '%1'").arg(newObject.value("face_image").toString()); - sql.append(QString(" WHERE PERSON_ID = %1").arg(id)); + QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = :faceImage WHERE ID = '%1'").arg(id); + + query.prepare(sql); + query.bindValue(":faceImage", newObject.value("face_image")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + LOG(DEBUG) << sql.toStdString(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool FaceDataImgDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA_IMAGE WHERE ID = '%1'").arg(id); LOG(DEBUG) << sql.toStdString(); @@ -183,11 +207,7 @@ // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); + // 返回结果 return success; } - -bool FaceDataImgDao::dele(QString id) -{ - return false; -} diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp index eabf262..8ec4c99 100644 --- a/dao/SysPersonDao.cpp +++ b/dao/SysPersonDao.cpp @@ -345,6 +345,14 @@ { sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } sql.append(QString(" WHERE ID = '%1'").arg(id)); @@ -375,11 +383,21 @@ QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1', DELFLAG = '%2' WHERE ID = '%3'") .arg(tm).arg(tmms).arg(id); + // 物理删除人员的人脸和虹膜数据 + QString delFaceSql = QString("DELETE FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(id); + QString delFaceImgSql = QString("DELETE FROM FACE_DATA_IMAGE WHERE PERSON_ID = '%1'").arg(id); + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = '%1'").arg(id); + QString delIrisImgSql = QString("DELETE FROM IRIS_DATA_IMAGE WHERE PERSON_ID = '%1'").arg(id); + // 开启事务 ConnectionManager::getInstance()->getConnection().transaction(); // 执行更新 bool success = query.exec(sql); + query.exec(delFaceSql); + query.exec(delFaceImgSql); + query.exec(delIrisSql); + query.exec(delIrisImgSql); // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/dao/FaceDataDao.cpp b/dao/FaceDataDao.cpp index 89a05da..7d1f873 100644 --- a/dao/FaceDataDao.cpp +++ b/dao/FaceDataDao.cpp @@ -30,21 +30,94 @@ result.append(item); } - LOG(TRACE) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); + LOG(DEBUG) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); return result; } QVariantMap FaceDataDao::findRecordById(QString id) { - QVariantMap item; - return item; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(DEBUG) << QString("根据id查询FACE_DATA表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); + return result; +} + +QVariantMap FaceDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(personId); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(TRACE) << QString("根据id查询FACE_DATA表的记录[personId=%1][%2]").arg(personId).arg(sql).toStdString(); + return result; } QVector FaceDataDao::findRecordsByProperty(QString properName, QVariant properValue) { + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM FACE_DATA WHERE %1 = '%2'"; + sql = sql.arg(properName).arg(properValue.toString()); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_code", query.value("face_code").toString()); + result.append(item); + } + + LOG(DEBUG) << QString("根据属性值查询FACE_DATA表的记录[%1][%2]").arg(count).arg(sql).toStdString(); return result; } @@ -89,10 +162,51 @@ bool FaceDataDao::edit(QVariantMap newObject, QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("face_code")){ + return false; + } + QString sql = QString("UPDATE FACE_DATA SET FACE_CODE = :faceCode WHERE ID = '%1'").arg(id); + query.prepare(sql); + query.bindValue(":faceCode", newObject.value("face_code")); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } bool FaceDataDao::dele(QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA WHERE ID = '%1'").arg(id); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } diff --git a/dao/FaceDataDao.h b/dao/FaceDataDao.h index 87fce40..6856a40 100644 --- a/dao/FaceDataDao.h +++ b/dao/FaceDataDao.h @@ -13,6 +13,7 @@ QVector findAllRecord(); QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); QVector findRecordsByProperty(QString properName, QVariant properValue); QString save(QVariantMap object); diff --git a/dao/FaceDataImgDao.cpp b/dao/FaceDataImgDao.cpp index d863752..7f3704e 100644 --- a/dao/FaceDataImgDao.cpp +++ b/dao/FaceDataImgDao.cpp @@ -23,7 +23,9 @@ while (query.next()) { QVariantMap item; - item.insert("id", query.value("id").toULongLong()); + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_image", query.value("face_image").toString()); result.append(item); } @@ -46,20 +48,15 @@ // 返回结果 QVariantMap result; - // 获取结果集的大小 - query.last(); - int count = query.at() + 1; - - if (count >=1) + // 获取结果 + if (query.next()) { - query.first(); - result.insert("id", query.value("id").toString()); result.insert("person_id", query.value("person_id").toString()); result.insert("face_image", query.value("face_image").toString()); } - LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(count).arg(sql).toStdString(); + LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); return result; } @@ -166,12 +163,39 @@ { // 新建查询 QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + // UPDATE语句 if (!newObject.contains("face_image")){ - return true; + return false; } - QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = '%1'").arg(newObject.value("face_image").toString()); - sql.append(QString(" WHERE PERSON_ID = %1").arg(id)); + QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = :faceImage WHERE ID = '%1'").arg(id); + + query.prepare(sql); + query.bindValue(":faceImage", newObject.value("face_image")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + LOG(DEBUG) << sql.toStdString(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool FaceDataImgDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA_IMAGE WHERE ID = '%1'").arg(id); LOG(DEBUG) << sql.toStdString(); @@ -183,11 +207,7 @@ // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); + // 返回结果 return success; } - -bool FaceDataImgDao::dele(QString id) -{ - return false; -} diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp index eabf262..8ec4c99 100644 --- a/dao/SysPersonDao.cpp +++ b/dao/SysPersonDao.cpp @@ -345,6 +345,14 @@ { sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } sql.append(QString(" WHERE ID = '%1'").arg(id)); @@ -375,11 +383,21 @@ QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1', DELFLAG = '%2' WHERE ID = '%3'") .arg(tm).arg(tmms).arg(id); + // 物理删除人员的人脸和虹膜数据 + QString delFaceSql = QString("DELETE FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(id); + QString delFaceImgSql = QString("DELETE FROM FACE_DATA_IMAGE WHERE PERSON_ID = '%1'").arg(id); + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = '%1'").arg(id); + QString delIrisImgSql = QString("DELETE FROM IRIS_DATA_IMAGE WHERE PERSON_ID = '%1'").arg(id); + // 开启事务 ConnectionManager::getInstance()->getConnection().transaction(); // 执行更新 bool success = query.exec(sql); + query.exec(delFaceSql); + query.exec(delFaceImgSql); + query.exec(delIrisSql); + query.exec(delIrisImgSql); // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); diff --git a/device/FaceCameraController.cpp b/device/FaceCameraController.cpp index fd9cb55..5f0e2ae 100644 --- a/device/FaceCameraController.cpp +++ b/device/FaceCameraController.cpp @@ -59,31 +59,31 @@ LOG(TRACE) << "TAKE ONE FACE FRAME " << faceMat.cols << " * " << faceMat.rows; - // clone一个mat, 用于界面显示 - cv::Mat faceMatDisp = faceMat.clone(); - // 左右翻转 cv::Mat imageMatMiir; - flip(faceMatDisp, imageMatMiir, 1); + flip(faceMat, imageMatMiir, 1); + + // clone一个mat, 用于界面显示 + cv::Mat faceMatDisp = imageMatMiir.clone(); // 利用人脸分类器进行初步的检测 - cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(imageMatMiir); + cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(faceMatDisp); if (faceRect.width > 0) { // 初筛检测到人脸时将图像入栈 CasicFaceInfo faceInfo; faceInfo.hasFace = false; - faceInfo.matData = faceMat; + faceInfo.matData = imageMatMiir; // 将图片数据压入堆栈 ProMemory::getInstance().pushCasicFace(faceInfo); // 检测到人脸则绘制一个绿色的边框 - rectangle(imageMatMiir, faceRect, cv::Scalar(0, 255, 0), 2); + rectangle(faceMatDisp, faceRect, cv::Scalar(0, 255, 0), 2); } // 将mat转成QImage - QImage imgDisplay = ImageUtil::MatImageToQImage(imageMatMiir); + QImage imgDisplay = ImageUtil::MatImageToQImage(faceMatDisp); // 发送信号用于界面显示 emit sendImageToDraw(imgDisplay); diff --git a/AddPersonForm.cpp b/AddPersonForm.cpp index 31bda26..adbcaa8 100644 --- a/AddPersonForm.cpp +++ b/AddPersonForm.cpp @@ -86,8 +86,8 @@ QImage image; QPixmap pixmap; image.loadFromData(QByteArray::fromBase64(imageData.toLatin1())); + image = image.scaledToHeight(240, Qt::SmoothTransformation); pixmap = QPixmap::fromImage(image); - pixmap.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pixmap); } } @@ -164,25 +164,36 @@ void AddPersonForm::onFailedCaptureFace() { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("没有找到人脸,请重试")); } -void AddPersonForm::onSuccessCaptureFace(QString personId) +void AddPersonForm::onSuccessCaptureFace(QString personIdByFace) { + // 隐藏人脸画面显示界面 faceLabel->hide(); + + // 停止拍图 ProMemory::getInstance().faceCam->stopTakingPhoto(); + + // 语音提示 SpeakerUtil::getInstance().speak(QString("人脸采集成功")); + LOG(DEBUG) << "人脸采集成功"; - if (personId == "") + if (personIdByFace == "") { // 人脸库中没有 // 设置显示人脸照片 face = CasicFaceRecState::getInstance().imgBase64; QPixmap pm; pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); - pm = pm.scaledToHeight(ui->labPhotoFace->height(), Qt::SmoothTransformation); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); ui->labPhotoFace->setPixmap(pm); // 计算特征值的字节数组 @@ -190,17 +201,74 @@ { faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); } + this->faceReCaptured = true; } else { - loadPersonInfo(personId); + // 命中人脸库中的某人 分以下情况 + // 1. this.personId == "" 表示是重复注册 加载人员信息并语音提示 + // 2. personIdByFace == this.personId 表示是同一个人重新采集人脸 只更新人脸照片和人脸特征值 + // 3. personIdByFace != this.personId 表示重新采集人脸时识别到另一人 需要重新编辑 + if (this->personId.isEmpty() == true) + { + // 情况1 重复注册 + loadPersonInfo(personIdByFace); - LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } else + { + if (this->personId == personIdByFace) + { + // 情况2 编辑本人 + face = CasicFaceRecState::getInstance().imgBase64; + QPixmap pm; + pm.loadFromData(QByteArray::fromBase64(face.toLocal8Bit())); + pm = pm.scaledToHeight(240, Qt::SmoothTransformation); + ui->labPhotoFace->setPixmap(pm); - ui->btnSave->setDisabled(true); + // 计算特征值的字节数组 + for (int i = 0; i < 1024; i++) + { + faceCode.append(ByteUtil::floatToBytes(CasicFaceRecState::getInstance().faceInfo->feature[i])); + } + + this->faceReCaptured = true; + } else { + // 情况3 编辑时非本人 人脸重复 + + // 语音提示 + SpeakerUtil::getInstance().speak(QString("人脸重复注册,请重试")); + LOG(DEBUG) << "人脸已经注册" << ui->inputName->text().toStdString(); + } + } } } bool AddPersonForm::validateForm() { + // 验证姓名字段 + QString nameValue = ui->inputName->text().trimmed(); + if (nameValue.isEmpty()) + { +// ui->inputName->setStyleSheet("border: 2px solid #FF1111;"); + ui->inputName->setPlaceholderText("姓名不能为空"); + return false; + } else + { + ui->inputName->setText(nameValue); +// ui->inputName->setStyleSheet("border: 1px solid #CCCCCC;"); + } + + // 验证所在部门 + int deptIndex = ui->selectDept->currentIndex(); + if (deptIndex == 0) + { +// ui->selectDept->setStyleSheet("border: 2px solid #FF1111;"); + return false; + } else + { +// ui->selectDept->setStyleSheet("border: 1px solid #CCCCCC;"); + } return true; } @@ -228,6 +296,40 @@ // 数据库操作 QString perIdReg = personDao.save(perToRegist); + // 注册人脸信息 + if (face.isEmpty() == false && faceCode.isEmpty() == false) + { + FaceDataDao faceDataDao; + FaceDataImgDao faceImgDao; + + QVariantMap faceVar; + faceVar.insert("person_id", perIdReg); + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + QString faceImgId = faceImgDao.save(faceVar); + if (faceImgId.toULongLong() > 0) + { + faceVar.insert("image_id", faceImgId); + } + QString faceCodeId = faceDataDao.save(faceVar); + + if (faceImgId.toULongLong() < 0 && faceCodeId.toULongLong() < 0) + { + OperationTipsDialog tipsDlg; + tipsDlg.setTipsDialogType(false); + tipsDlg.setTipsText(QString("%1 人脸保存失败").arg(ui->inputName->text())); + tipsDlg.exec(); + return; + } else { + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, perIdReg); + } + } + + // 注册虹膜信息 + // 弹出提示框 bool succ = perIdReg == "-1" ? false : true; OperationTipsDialog tipsDlg; @@ -237,10 +339,6 @@ LOG(INFO) << QString("%1 人员注册%2").arg(ui->inputName->text()).arg(succ == true ? "成功" : "失败").toStdString(); - // 注册人脸信息 - - // 注册虹膜信息 - if (ret == 1) { emit switchToUserListForm(); @@ -269,6 +367,57 @@ // 数据库操作 bool succ = personDao.edit(perToEdit, personId); + // 需要更新人脸数据 + if(this->faceReCaptured == true && + face.isEmpty() == false && faceCode.isEmpty() == false) + { + QVariantMap faceVar; + faceVar.insert("face_image", face); + faceVar.insert("face_code", faceCode); + + QString faceImgId; + QString faceCodeId; + + // 更新人脸图像数据 + FaceDataImgDao faceImgDao; + QVariantMap faceImageRec = faceImgDao.findRecordByPersonId(personId); // 查找人脸照片数据库记录 + if (faceImageRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸图像 + faceVar.insert("person_id", personId); + faceImgId = faceImgDao.save(faceVar); + } else { + // 找到一条记录 + faceImgId = faceImageRec.value("id").toString(); + faceImgDao.edit(faceVar, faceImgId); + } + + // 更新人脸特征值数据 + FaceDataDao faceDataDao; + QVariantMap faceCodeRec = faceDataDao.findRecordByPersonId(personId); // 查找人脸特征值数据库记录 + if (faceCodeRec.isEmpty() == true) + { + // 没有找到记录 需要新增一条人脸特征值 + faceVar.insert("person_id", personId); + faceVar.insert("image_id", faceImgId); + faceCodeId = faceDataDao.save(faceVar); + } else { + // 找到一条记录 + faceCodeId = faceCodeRec.value("id").toString(); + faceDataDao.edit(faceVar, faceCodeId); + } + + this->faceReCaptured = false; + + // 人脸保存成功 更新SYS_PERSON表的人脸字段 + QVariantMap faceValid; + faceValid.insert("face_valid", "1"); + personDao.edit(faceValid, personId); + + // 重新加载人脸库 + ProMemory::getInstance().initFaceFeatures(); + } + // 弹出提示框 OperationTipsDialog tipsDlg; tipsDlg.setTipsDialogType(succ); diff --git a/AddPersonForm.h b/AddPersonForm.h index ae9a154..de41459 100644 --- a/AddPersonForm.h +++ b/AddPersonForm.h @@ -33,7 +33,7 @@ public slots: void drawImageOnForm(QImage imageDisp); void onFailedCaptureFace(); - void onSuccessCaptureFace(QString personId); + void onSuccessCaptureFace(QString personIdByFace); private slots: void on_btnBack_clicked(); @@ -52,6 +52,7 @@ QString face; // 人脸图像数据 QByteArray faceCode; // 人脸特征编码数据 + bool faceReCaptured; // 编辑时是否需要更新人脸数据 QLabel * faceLabel; // 采集人脸时显示的画面 diff --git a/CasicBioRecWin.cpp b/CasicBioRecWin.cpp index 2179273..fe3819d 100644 --- a/CasicBioRecWin.cpp +++ b/CasicBioRecWin.cpp @@ -43,9 +43,8 @@ ProMemory::getInstance().faceRegistPro->deleteLater(); ProMemory::getInstance().faceRegistPro->wait(); - delete ProMemory::getInstance().faceRegistPro; - delete ui; + delete ProMemory::getInstance().faceRegistPro; } void CasicBioRecWin::keyPressEvent(QKeyEvent *event) diff --git a/dao/FaceDataDao.cpp b/dao/FaceDataDao.cpp index 89a05da..7d1f873 100644 --- a/dao/FaceDataDao.cpp +++ b/dao/FaceDataDao.cpp @@ -30,21 +30,94 @@ result.append(item); } - LOG(TRACE) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); + LOG(DEBUG) << QString("查询FACE_DATA表的所有记录[%1]").arg(result.size()).toStdString(); return result; } QVariantMap FaceDataDao::findRecordById(QString id) { - QVariantMap item; - return item; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE ID = '%1'").arg(id); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + // 获取结果 + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(DEBUG) << QString("根据id查询FACE_DATA表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); + return result; +} + +QVariantMap FaceDataDao::findRecordByPersonId(QString personId) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = QString("SELECT * FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(personId); + + // 执行查询 + query.exec(sql); + + // 返回结果 + QVariantMap result; + + if (query.next()) + { + result.insert("id", query.value("id").toString()); + result.insert("person_id", query.value("person_id").toString()); + result.insert("face_code", query.value("face_code").toString()); + } + + LOG(TRACE) << QString("根据id查询FACE_DATA表的记录[personId=%1][%2]").arg(personId).arg(sql).toStdString(); + return result; } QVector FaceDataDao::findRecordsByProperty(QString properName, QVariant properValue) { + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // 查询语句 + QString sql = "SELECT * FROM FACE_DATA WHERE %1 = '%2'"; + sql = sql.arg(properName).arg(properValue.toString()); + + // 执行查询 + query.exec(sql); + + // 获取结果集的大小 + int count = 0; + + // 返回结果 QVector result; + + // 遍历查询结果 + while (query.next()) { + QVariantMap item; + + count++; + + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_code", query.value("face_code").toString()); + result.append(item); + } + + LOG(DEBUG) << QString("根据属性值查询FACE_DATA表的记录[%1][%2]").arg(count).arg(sql).toStdString(); return result; } @@ -89,10 +162,51 @@ bool FaceDataDao::edit(QVariantMap newObject, QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // UPDATE语句 + if (!newObject.contains("face_code")){ + return false; + } + QString sql = QString("UPDATE FACE_DATA SET FACE_CODE = :faceCode WHERE ID = '%1'").arg(id); + query.prepare(sql); + query.bindValue(":faceCode", newObject.value("face_code")); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } bool FaceDataDao::dele(QString id) { - return false; + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA WHERE ID = '%1'").arg(id); + + LOG(DEBUG) << sql.toStdString(); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(sql); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; } diff --git a/dao/FaceDataDao.h b/dao/FaceDataDao.h index 87fce40..6856a40 100644 --- a/dao/FaceDataDao.h +++ b/dao/FaceDataDao.h @@ -13,6 +13,7 @@ QVector findAllRecord(); QVariantMap findRecordById(QString id); + QVariantMap findRecordByPersonId(QString personId); QVector findRecordsByProperty(QString properName, QVariant properValue); QString save(QVariantMap object); diff --git a/dao/FaceDataImgDao.cpp b/dao/FaceDataImgDao.cpp index d863752..7f3704e 100644 --- a/dao/FaceDataImgDao.cpp +++ b/dao/FaceDataImgDao.cpp @@ -23,7 +23,9 @@ while (query.next()) { QVariantMap item; - item.insert("id", query.value("id").toULongLong()); + item.insert("id", query.value("id").toString()); + item.insert("person_id", query.value("person_id").toString()); + item.insert("face_image", query.value("face_image").toString()); result.append(item); } @@ -46,20 +48,15 @@ // 返回结果 QVariantMap result; - // 获取结果集的大小 - query.last(); - int count = query.at() + 1; - - if (count >=1) + // 获取结果 + if (query.next()) { - query.first(); - result.insert("id", query.value("id").toString()); result.insert("person_id", query.value("person_id").toString()); result.insert("face_image", query.value("face_image").toString()); } - LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(count).arg(sql).toStdString(); + LOG(DEBUG) << QString("根据id查询FACE_DATA_IMAGE表的记录[%1][%2]").arg(result.size()).arg(sql).toStdString(); return result; } @@ -166,12 +163,39 @@ { // 新建查询 QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + // UPDATE语句 if (!newObject.contains("face_image")){ - return true; + return false; } - QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = '%1'").arg(newObject.value("face_image").toString()); - sql.append(QString(" WHERE PERSON_ID = %1").arg(id)); + QString sql = QString("UPDATE FACE_DATA_IMAGE SET FACE_IMAGE = :faceImage WHERE ID = '%1'").arg(id); + + query.prepare(sql); + query.bindValue(":faceImage", newObject.value("face_image")); + + // 开启事务 + ConnectionManager::getInstance()->getConnection().transaction(); + + // 执行更新 + bool success = query.exec(); + + LOG(DEBUG) << sql.toStdString(); + + // 结束事务 + ConnectionManager::getInstance()->getConnection().commit(); + + // 返回结果 + return success; +} + + +bool FaceDataImgDao::dele(QString id) +{ + // 新建查询 + QSqlQuery query(ConnectionManager::getInstance()->getConnection()); + + // DELETE + QString sql = QString("DELETE FROM FACE_DATA_IMAGE WHERE ID = '%1'").arg(id); LOG(DEBUG) << sql.toStdString(); @@ -183,11 +207,7 @@ // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); + // 返回结果 return success; } - -bool FaceDataImgDao::dele(QString id) -{ - return false; -} diff --git a/dao/SysPersonDao.cpp b/dao/SysPersonDao.cpp index eabf262..8ec4c99 100644 --- a/dao/SysPersonDao.cpp +++ b/dao/SysPersonDao.cpp @@ -345,6 +345,14 @@ { sql.append(QString(", PERSON_CODE = '%1'").arg(newObject.value("person_code").toString())); } + if (newObject.contains("face_valid")) + { + sql.append(QString(", FACE_VALID = '%1'").arg(newObject.value("face_valid").toString())); + } + if (newObject.contains("iris_valid")) + { + sql.append(QString(", IRIS_VALID = '%1'").arg(newObject.value("iris_valid").toString())); + } sql.append(QString(" WHERE ID = '%1'").arg(id)); @@ -375,11 +383,21 @@ QString sql = QString("UPDATE SYS_PERSON SET UPDATETIME = '%1', DELFLAG = '%2' WHERE ID = '%3'") .arg(tm).arg(tmms).arg(id); + // 物理删除人员的人脸和虹膜数据 + QString delFaceSql = QString("DELETE FROM FACE_DATA WHERE PERSON_ID = '%1'").arg(id); + QString delFaceImgSql = QString("DELETE FROM FACE_DATA_IMAGE WHERE PERSON_ID = '%1'").arg(id); + QString delIrisSql = QString("DELETE FROM IRIS_DATA WHERE PERSON_ID = '%1'").arg(id); + QString delIrisImgSql = QString("DELETE FROM IRIS_DATA_IMAGE WHERE PERSON_ID = '%1'").arg(id); + // 开启事务 ConnectionManager::getInstance()->getConnection().transaction(); // 执行更新 bool success = query.exec(sql); + query.exec(delFaceSql); + query.exec(delFaceImgSql); + query.exec(delIrisSql); + query.exec(delIrisImgSql); // 结束事务 ConnectionManager::getInstance()->getConnection().commit(); diff --git a/device/FaceCameraController.cpp b/device/FaceCameraController.cpp index fd9cb55..5f0e2ae 100644 --- a/device/FaceCameraController.cpp +++ b/device/FaceCameraController.cpp @@ -59,31 +59,31 @@ LOG(TRACE) << "TAKE ONE FACE FRAME " << faceMat.cols << " * " << faceMat.rows; - // clone一个mat, 用于界面显示 - cv::Mat faceMatDisp = faceMat.clone(); - // 左右翻转 cv::Mat imageMatMiir; - flip(faceMatDisp, imageMatMiir, 1); + flip(faceMat, imageMatMiir, 1); + + // clone一个mat, 用于界面显示 + cv::Mat faceMatDisp = imageMatMiir.clone(); // 利用人脸分类器进行初步的检测 - cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(imageMatMiir); + cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(faceMatDisp); if (faceRect.width > 0) { // 初筛检测到人脸时将图像入栈 CasicFaceInfo faceInfo; faceInfo.hasFace = false; - faceInfo.matData = faceMat; + faceInfo.matData = imageMatMiir; // 将图片数据压入堆栈 ProMemory::getInstance().pushCasicFace(faceInfo); // 检测到人脸则绘制一个绿色的边框 - rectangle(imageMatMiir, faceRect, cv::Scalar(0, 255, 0), 2); + rectangle(faceMatDisp, faceRect, cv::Scalar(0, 255, 0), 2); } // 将mat转成QImage - QImage imgDisplay = ImageUtil::MatImageToQImage(imageMatMiir); + QImage imgDisplay = ImageUtil::MatImageToQImage(faceMatDisp); // 发送信号用于界面显示 emit sendImageToDraw(imgDisplay); diff --git a/device/face/FaceDetectRegistProcess.h b/device/face/FaceDetectRegistProcess.h index 4df7708..9ffa91d 100644 --- a/device/face/FaceDetectRegistProcess.h +++ b/device/face/FaceDetectRegistProcess.h @@ -42,7 +42,7 @@ signals: void extractFeatureSuccess(); void failedCaptureFace(); - void successCaptureFace(QString personId); + void successCaptureFace(QString personIdByFace); void findSimFace(QString personId); };