class Camera(QMainWindow): def __init__(self, parent=None): super(Camera, self).__init__(parent) self.ui = Ui_Camera() self.camera = None self.imageCapture = None # self.mediaRecorder = None self.isCapturingImage = False self.applicationExiting = False self.imageSettings = QImageEncoderSettings() self.audioSettings = QAudioEncoderSettings() # self.videoSettings = QVideoEncoderSettings() # self.videoContainerFormat = '' self.ui.setupUi(self) cameraDevice = QByteArray() videoDevicesGroup = QActionGroup(self) videoDevicesGroup.setExclusive(True) for deviceName in QCamera.availableDevices(): description = QCamera.deviceDescription(deviceName) videoDeviceAction = QAction(description, videoDevicesGroup) videoDeviceAction.setCheckable(True) videoDeviceAction.setData(deviceName) if cameraDevice.isEmpty(): cameraDevice = deviceName videoDeviceAction.setChecked(True) self.ui.menuDevices.addAction(videoDeviceAction) videoDevicesGroup.triggered.connect(self.updateCameraDevice) self.ui.captureWidget.currentChanged.connect(self.updateCaptureMode) #self.ui.lockButton.hide() self.setCamera(cameraDevice) def setCamera(self, cameraDevice): if cameraDevice.isEmpty(): self.camera = QCamera() else: self.camera = QCamera(cameraDevice) self.camera.stateChanged.connect(self.updateCameraState) self.camera.error.connect(self.displayCameraError) # self.mediaRecorder = QMediaRecorder(self.camera) # self.mediaRecorder.stateChanged.connect(self.updateRecorderState) self.imageCapture = QCameraImageCapture(self.camera) # self.mediaRecorder.durationChanged.connect(self.updateRecordTime) # self.mediaRecorder.error.connect(self.displayRecorderError) # self.mediaRecorder.setMetaData(QMediaMetaData.Title, "Test Title") # self.ui.exposureCompensation.valueChanged.connect( # self.setExposureCompensation) self.camera.setViewfinder(self.ui.viewfinder) self.updateCameraState(self.camera.state()) # self.updateLockStatus(self.camera.lockStatus(), QCamera.UserRequest) # self.updateRecorderState(self.mediaRecorder.state()) self.imageCapture.readyForCaptureChanged.connect(self.readyForCapture) self.imageCapture.imageCaptured.connect(self.processCapturedImage) self.imageCapture.imageSaved.connect(self.imageSaved) # self.camera.lockStatusChanged.connect(self.updateLockStatus) self.ui.captureWidget.setTabEnabled( 0, self.camera.isCaptureModeSupported(QCamera.CaptureStillImage)) self.ui.captureWidget.setTabEnabled( 1, self.camera.isCaptureModeSupported(QCamera.CaptureVideo)) self.updateCaptureMode() self.camera.start() def keyPressEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.displayViewfinder() self.camera.searchAndLock() event.accept() elif event.key() == Qt.Key_Camera: if self.camera.captureMode() == QCamera.CaptureStillImage: self.takeImage() # elif self.mediaRecorder.state() == QMediaRecorder.RecordingState: # self.stop() # else: # self.record() event.accept() else: super(Camera, self).keyPressEvent(event) def keyReleaseEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.camera.unlock() else: super(Camera, self).keyReleaseEvent(event) # def updateRecordTime(self): # msg = "Recorded %d sec" % (self.mediaRecorder.duration() // 1000) # self.ui.statusbar.showMessage(msg) def processCapturedImage(self, requestId, img): scaledImage = img.scaled(self.ui.viewfinder.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.ui.lastImagePreviewLabel.setPixmap(QPixmap.fromImage(scaledImage)) self.displayCapturedImage() QTimer.singleShot(4000, self.displayViewfinder) def configureCaptureSettings(self): if self.camera.captureMode() == QCamera.CaptureStillImage: self.configureImageSettings() elif self.camera.captureMode() == QCamera.CaptureVideo: self.configureVideoSettings() # def configureVideoSettings(self): # settingsDialog = VideoSettings(self.mediaRecorder) # settingsDialog.setAudioSettings(self.audioSettings) # settingsDialog.setVideoSettings(self.videoSettings) # settingsDialog.setFormat(self.videoContainerFormat) # if settingsDialog.exec_(): # self.audioSettings = settingsDialog.audioSettings() # self.videoSettings = settingsDialog.videoSettings() # self.videoContainerFormat = settingsDialog.format() # self.mediaRecorder.setEncodingSettings(self.audioSettings, # self.videoSettings, self.videoContainerFormat) def configureOpenExcels(self): settingsopenexcelDialog = OpenExcels() settingsopenexcelDialog.initUI() def configureImageSettings(self): settingsDialog = ImageSettings(self.imageCapture) settingsDialog.setImageSettings(self.imageSettings) if settingsDialog.exec_(): self.imageSettings = settingsDialog.imageSettings() self.imageCapture.setEncodingSettings(self.imageSettings) # def record(self): # self.mediaRecorder.record() # self.updateRecordTime() # def pause(self): # self.mediaRecorder.pause() # def stop(self): # self.mediaRecorder.stop() # def setMuted(self, muted): # self.mediaRecorder.setMuted(muted) def toggleLock(self): if self.camera.lockStatus() in (QCamera.Searching, QCamera.Locked): self.camera.unlock() elif self.camera.lockStatus() == QCamera.Unlocked: self.camera.searchAndLock() # def updateLockStatus(self, status, reason): # indicationColor = Qt.black # if status == QCamera.Searching: # self.ui.statusbar.showMessage("Focusing...") # self.ui.lockButton.setText("Focusing...") # indicationColor = Qt.yellow # elif status == QCamera.Locked: # self.ui.lockButton.setText("Unlock") # self.ui.statusbar.showMessage("Focused", 2000) # indicationColor = Qt.darkGreen # # elif status == QCamera.Unlocked: # # self.ui.lockButton.setText("Focus") # if reason == QCamera.LockFailed: # self.ui.statusbar.showMessage("Focus Failed", 2000) # indicationColor = Qt.red # palette = self.ui.lockButton.palette() # palette.setColor(QPalette.ButtonText, indicationColor) # self.ui.lockButton.setPalette(palette) def display_absences(self, absences): self.ui.absenceNumber.display(absences) def takeImage(self): self.isCapturingImage = True self.imageCapture.capture() def startCamera(self): self.camera.start() def stopCamera(self): self.camera.stop() def updateCaptureMode(self): tabIndex = self.ui.captureWidget.currentIndex() captureMode = QCamera.CaptureStillImage if tabIndex == 0 else QCamera.CaptureVideo if self.camera.isCaptureModeSupported(captureMode): self.camera.setCaptureMode(captureMode) def updateCameraState(self, state): if state == QCamera.ActiveState: self.ui.actionStartCamera.setEnabled(False) self.ui.actionStopCamera.setEnabled(True) self.ui.captureWidget.setEnabled(True) self.ui.actionSettings.setEnabled(True) elif state in (QCamera.UnloadedState, QCamera.LoadedState): self.ui.actionStartCamera.setEnabled(True) self.ui.actionStopCamera.setEnabled(False) self.ui.captureWidget.setEnabled(False) self.ui.actionSettings.setEnabled(False) # def updateRecorderState(self, state): # if state == QMediaRecorder.StoppedState: # # self.ui.recordButton.setEnabled(True) # self.ui.pauseButton.setEnabled(True) # self.ui.stopButton.setEnabled(False) # elif state == QMediaRecorder.PausedState: # self.ui.recordButton.setEnabled(True) # self.ui.pauseButton.setEnabled(False) # self.ui.stopButton.setEnabled(True) # elif state == QMediaRecorder.RecordingState: # self.ui.recordButton.setEnabled(False) # self.ui.pauseButton.setEnabled(True) # self.ui.stopButton.setEnabled(True) def setExposureCompensation(self, index): self.camera.exposure().setExposureCompensation(index * 0.5) # def displayRecorderError(self): # QMessageBox.warning(self, "Capture error", # self.mediaRecorder.errorString()) def displayCameraError(self): QMessageBox.warning(self, "Camera error", self.camera.errorString()) def updateCameraDevice(self, action): self.setCamera(action.data()) def displayViewfinder(self): self.ui.stackedWidget.setCurrentIndex(0) def displayCapturedImage(self): self.ui.stackedWidget.setCurrentIndex(1) def readyForCapture(self, ready): self.ui.takeImageButton.setEnabled(ready) def imageSaved(self, id, fileName): self.isCapturingImage = False if self.applicationExiting: self.close() def closeEvent(self, event): if self.isCapturingImage: self.setEnabled(False) self.applicationExiting = True event.ignore() else: event.accept()
class Camera(QMainWindow): def __init__(self, parent=None): super(Camera, self).__init__(parent) self.ui = Ui_Camera() self.camera = None self.imageCapture = None self.mediaRecorder = None self.isCapturingImage = False self.applicationExiting = False self.imageSettings = QImageEncoderSettings() self.audioSettings = QAudioEncoderSettings() self.videoSettings = QVideoEncoderSettings() self.videoContainerFormat = '' self.ui.setupUi(self) cameraDevice = QByteArray() videoDevicesGroup = QActionGroup(self) videoDevicesGroup.setExclusive(True) for deviceName in QCamera.availableDevices(): description = QCamera.deviceDescription(deviceName) videoDeviceAction = QAction(description, videoDevicesGroup) videoDeviceAction.setCheckable(True) videoDeviceAction.setData(deviceName) if cameraDevice.isEmpty(): cameraDevice = deviceName videoDeviceAction.setChecked(True) self.ui.menuDevices.addAction(videoDeviceAction) videoDevicesGroup.triggered.connect(self.updateCameraDevice) self.ui.captureWidget.currentChanged.connect(self.updateCaptureMode) self.ui.lockButton.hide() self.setCamera(cameraDevice) def setCamera(self, cameraDevice): if cameraDevice.isEmpty(): self.camera = QCamera() else: self.camera = QCamera(cameraDevice) self.camera.stateChanged.connect(self.updateCameraState) self.camera.error.connect(self.displayCameraError) self.mediaRecorder = QMediaRecorder(self.camera) self.mediaRecorder.stateChanged.connect(self.updateRecorderState) self.imageCapture = QCameraImageCapture(self.camera) self.mediaRecorder.durationChanged.connect(self.updateRecordTime) self.mediaRecorder.error.connect(self.displayRecorderError) self.mediaRecorder.setMetaData(QMediaMetaData.Title, "Test Title") self.ui.exposureCompensation.valueChanged.connect( self.setExposureCompensation) self.camera.setViewfinder(self.ui.viewfinder) self.updateCameraState(self.camera.state()) self.updateLockStatus(self.camera.lockStatus(), QCamera.UserRequest) self.updateRecorderState(self.mediaRecorder.state()) self.imageCapture.readyForCaptureChanged.connect(self.readyForCapture) self.imageCapture.imageCaptured.connect(self.processCapturedImage) self.imageCapture.imageSaved.connect(self.imageSaved) self.camera.lockStatusChanged.connect(self.updateLockStatus) self.ui.captureWidget.setTabEnabled(0, self.camera.isCaptureModeSupported(QCamera.CaptureStillImage)) self.ui.captureWidget.setTabEnabled(1, self.camera.isCaptureModeSupported(QCamera.CaptureVideo)) self.updateCaptureMode() self.camera.start() def keyPressEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.displayViewfinder() self.camera.searchAndLock() event.accept() elif event.key() == Qt.Key_Camera: if self.camera.captureMode() == QCamera.CaptureStillImage: self.takeImage() elif self.mediaRecorder.state() == QMediaRecorder.RecordingState: self.stop() else: self.record() event.accept() else: super(Camera, self).keyPressEvent(event) def keyReleaseEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.camera.unlock() else: super(Camera, self).keyReleaseEvent(event) def updateRecordTime(self): msg = "Recorded %d sec" % self.mediaRecorder.duration() // 1000 self.ui.statusbar.showMessage(msg) def processCapturedImage(self, requestId, img): scaledImage = img.scaled(self.ui.viewfinder.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.ui.lastImagePreviewLabel.setPixmap(QPixmap.fromImage(scaledImage)) self.displayCapturedImage() QTimer.singleShot(4000, self.displayViewfinder) def configureCaptureSettings(self): if self.camera.captureMode() == QCamera.CaptureStillImage: self.configureImageSettings() elif self.camera.captureMode() == QCamera.CaptureVideo: self.configureVideoSettings() def configureVideoSettings(self): settingsDialog = VideoSettings(self.mediaRecorder) settingsDialog.setAudioSettings(self.audioSettings) settingsDialog.setVideoSettings(self.videoSettings) settingsDialog.setFormat(self.videoContainerFormat) if settingsDialog.exec_(): self.audioSettings = settingsDialog.audioSettings() self.videoSettings = settingsDialog.videoSettings() self.videoContainerFormat = settingsDialog.format() self.mediaRecorder.setEncodingSettings(self.audioSettings, self.videoSettings, self.videoContainerFormat) def configureImageSettings(self): settingsDialog = ImageSettings(self.imageCapture) settingsDialog.setImageSettings(self.imageSettings) if settingsDialog.exec_(): self.imageSettings = settingsDialog.imageSettings() imageCapture.setEncodingSettings(self.imageSettings) def record(self): self.mediaRecorder.record() self.updateRecordTime() def pause(self): self.mediaRecorder.pause() def stop(self): self.mediaRecorder.stop() def setMuted(self, muted): self.mediaRecorder.setMuted(muted) def toggleLock(self): if self.camera.lockStatus() in (QCamera.Searching, QCamera.Locked): self.camera.unlock() elif self.camera.lockStatus() == QCamera.Unlocked: self.camera.searchAndLock() def updateLockStatus(self, status, reason): indicationColor = Qt.black if status == QCamera.Searching: self.ui.statusbar.showMessage("Focusing...") self.ui.lockButton.setText("Focusing...") indicationColor = Qt.yellow elif status == QCamera.Locked: self.ui.lockButton.setText("Unlock") self.ui.statusbar.showMessage("Focused", 2000) indicationColor = Qt.darkGreen elif status == QCamera.Unlocked: self.ui.lockButton.setText("Focus") if reason == QCamera.LockFailed: self.ui.statusbar.showMessage("Focus Failed", 2000) indicationColor = Qt.red palette = self.ui.lockButton.palette() palette.setColor(QPalette.ButtonText, indicationColor) self.ui.lockButton.setPalette(palette) def takeImage(self): self.isCapturingImage = True self.imageCapture.capture() def startCamera(self): self.camera.start() def stopCamera(self): self.camera.stop() def updateCaptureMode(self): tabIndex = self.ui.captureWidget.currentIndex() captureMode = QCamera.CaptureStillImage if tabIndex == 0 else QCamera.CaptureVideo if self.camera.isCaptureModeSupported(captureMode): self.camera.setCaptureMode(captureMode) def updateCameraState(self, state): if state == QCamera.ActiveState: self.ui.actionStartCamera.setEnabled(False) self.ui.actionStopCamera.setEnabled(True) self.ui.captureWidget.setEnabled(True) self.ui.actionSettings.setEnabled(True) elif state in (QCamera.UnloadedState, QCamera.LoadedState): self.ui.actionStartCamera.setEnabled(True) self.ui.actionStopCamera.setEnabled(False) self.ui.captureWidget.setEnabled(False) self.ui.actionSettings.setEnabled(False) def updateRecorderState(self, state): if state == QMediaRecorder.StoppedState: self.ui.recordButton.setEnabled(True) self.ui.pauseButton.setEnabled(True) self.ui.stopButton.setEnabled(False) elif state == QMediaRecorder.PausedState: self.ui.recordButton.setEnabled(True) self.ui.pauseButton.setEnabled(False) self.ui.stopButton.setEnabled(True) elif state == QMediaRecorder.RecordingState: self.ui.recordButton.setEnabled(False) self.ui.pauseButton.setEnabled(True) self.ui.stopButton.setEnabled(True) def setExposureCompensation(self, index): self.camera.exposure().setExposureCompensation(index * 0.5) def displayRecorderError(self): QMessageBox.warning(self, "Capture error", self.mediaRecorder.errorString()) def displayCameraError(self): QMessageBox.warning(self, "Camera error", self.camera.errorString()) def updateCameraDevice(self, action): self.setCamera(action.data()) def displayViewfinder(self): self.ui.stackedWidget.setCurrentIndex(0) def displayCapturedImage(self): self.ui.stackedWidget.setCurrentIndex(1) def readyForCapture(self, ready): self.ui.takeImageButton.setEnabled(ready) def imageSaved(self, id, fileName): self.isCapturingImage = False if self.applicationExiting: self.close() def closeEvent(self, event): if self.isCapturingImage: self.setEnabled(False) self.applicationExiting = True event.ignore() else: event.accept()
class CQCameraPreviewWindow(QtWidgets.QMainWindow): closeSignal = QtCore.pyqtSignal() ioctlRequest = QtCore.pyqtSignal(dict) def __init__(self, *args, **kwargs): super(CQCameraPreviewWindow, self).__init__(*args, **kwargs) self._MIN_WIN_WIDTH = 640 self.oc_camera_info = None self.oc_camera = None self.b_guard = False self.toolbar = QtWidgets.QToolBar("Preview") self.cbox_resolution = CLabeledComboBox("Resolution:") self.cbox_resolution.cbox.currentIndexChanged.connect(self.__cb_on_resolution_cbox_index_changed) self.toolbar.addWidget(self.cbox_resolution) self.toolbar.addSeparator() self.cbox_frame_rate = CLabeledComboBox("Frame Rate:") self.cbox_frame_rate.cbox.currentIndexChanged.connect(self.__cb_on_frame_rate_cbox_index_changed) self.toolbar.addWidget(self.cbox_frame_rate) self.addToolBar(self.toolbar) self.toolbar.addSeparator() self.oc_view_finder = QCameraViewfinder() self.setCentralWidget(self.oc_view_finder) def __cb_on_resolution_cbox_index_changed(self, i_idx): if self.oc_camera is None: self.fatal_error("Unallocated camera object detected") if self.b_guard: return l_res = self.cbox_resolution.cbox.itemText(i_idx).split(" x ") oc_vf_settings = self.oc_camera.viewfinderSettings() if oc_vf_settings.isNull(): self.fatal_error("Unable to retrieve camera settings") i_w, i_h = int(l_res[0]), int(l_res[1]) oc_vf_settings.setResolution(i_w, i_h) self.oc_camera.setViewfinderSettings(oc_vf_settings) self.oc_view_finder.setFixedSize(i_w, i_h) if i_w >= self._MIN_WIN_WIDTH: self.adjustSize() self.setFixedSize(self.sizeHint()) def __cb_on_frame_rate_cbox_index_changed(self, i_idx): if self.oc_camera is None: self.fatal_error("Unallocated camera object detected") if self.b_guard: return f_res = float(self.cbox_frame_rate.cbox.itemText(i_idx)) oc_vf_settings = self.oc_camera.viewfinderSettings() if oc_vf_settings.isNull(): self.fatal_error("Unable to retrieve camera settings") oc_vf_settings.setMinimumFrameRate(f_res) oc_vf_settings.setMaximumFrameRate(f_res) self.oc_camera.setViewfinderSettings(oc_vf_settings) def __camera_sync_start(self): i_sec_cnt = 0 self.oc_camera.start() while True: cam_status = self.oc_camera.status() if cam_status == QCamera.ActiveStatus: break else: time.sleep(1) i_sec_cnt += 1 if i_sec_cnt >= 10: self.fatal_error("Unable to start the camera") def __update_UI(self): # retrieve all supported resolutions and populate the resolution combo box l_resolutions = self.oc_camera.supportedViewfinderResolutions() if len(l_resolutions) > 0: l_res = [] for oc_res in l_resolutions: l_res.append("%i x %i" % (oc_res.width(), oc_res.height())) self.cbox_resolution.cbox.clear() self.cbox_resolution.cbox.addItems(l_res) oc_vf_settings = self.oc_camera.viewfinderSettings() if oc_vf_settings.isNull(): self.fatal_error("Unable to retrieve camera settings") # set current item index in the resolution combo box # according to the current resolution of our camera oc_curr_res = oc_vf_settings.resolution() s_res_hash = "%i x %i" % (oc_curr_res.width(), oc_curr_res.height()) for i_idx in range(self.cbox_resolution.cbox.count()): if self.cbox_resolution.cbox.itemText(i_idx) == s_res_hash: self.cbox_resolution.cbox.setCurrentIndex(i_idx) # retrieve all supported frame rates and populate the frame rate combo box l_frates = self.oc_camera.supportedViewfinderFrameRateRanges() if len(l_frates) > 0: l_res = [] for oc_frate in l_frates: l_res.append("%f" % oc_frate.minimumFrameRate) self.cbox_frame_rate.cbox.clear() self.cbox_frame_rate.cbox.addItems(l_res) # set current item index in the frame rate combo box # according to the current frame rate of our camera i_curr_frate = int(oc_vf_settings.minimumFrameRate()) for i_idx in range(self.cbox_frame_rate.cbox.count()): if int(float(self.cbox_frame_rate.cbox.itemText(i_idx))) == i_curr_frate: self.cbox_frame_rate.cbox.setCurrentIndex(i_idx) def fatal_error(self, s_msg): if self.oc_camera is not None: self.oc_camera.stop() QtWidgets.QMessageBox.critical(None, "Fatal Error", "%s\nThe application will exit now." % s_msg) sys.exit(-1) def start_preview(self, oc_camera_info, oc_frame_cap_thread): if self.oc_camera is not None: self.fatal_error("Preallocated camera object detected") self.oc_camera_info = oc_camera_info self.oc_camera = QCamera(self.oc_camera_info) self.oc_camera.setViewfinder(self.oc_view_finder) self.oc_camera.setCaptureMode(QCamera.CaptureVideo) self.oc_camera.error.connect(lambda: self.show_error_message(self.oc_camera.errorString())) self.b_guard = True self.__camera_sync_start() self.__update_UI() self.b_guard = False self.setWindowTitle(self.oc_camera_info.description()) self.adjustSize() self.setFixedSize(self.sizeHint()) def stop_preview(self): if self.oc_camera is None: return # this is correct logic, no error here self.oc_camera.stop() self.oc_camera.unload() self.oc_camera = None self.oc_camera_info = None def is_save_state_needed(self): return False def save_state(self): pass def show_error_message(self, s_msg): err = QtWidgets.QErrorMessage(self) err.showMessage(s_msg) def closeEvent(self, event): if self.is_save_state_needed(): self.save_state() self.stop_preview() self.closeSignal.emit()
class Camera(QMainWindow): def __init__(self, parent=None): super(Camera, self).__init__(parent) self.ui = Ui_Camera() self.camera = None self.imageCapture = None self.mediaRecorder = None self.isCapturingImage = False self.applicationExiting = False self.imageSettings = QImageEncoderSettings() self.audioSettings = QAudioEncoderSettings() self.videoSettings = QVideoEncoderSettings() self.videoContainerFormat = '' self.ui.setupUi(self) cameraDevice = QByteArray() videoDevicesGroup = QActionGroup(self) videoDevicesGroup.setExclusive(True) for deviceName in QCamera.availableDevices(): description = QCamera.deviceDescription(deviceName) videoDeviceAction = QAction(description, videoDevicesGroup) videoDeviceAction.setCheckable(True) videoDeviceAction.setData(deviceName) if cameraDevice.isEmpty(): cameraDevice = deviceName videoDeviceAction.setChecked(True) self.ui.menuDevices.addAction(videoDeviceAction) videoDevicesGroup.triggered.connect(self.updateCameraDevice) self.ui.captureWidget.currentChanged.connect(self.updateCaptureMode) self.ui.lockButton.hide() self.setCamera(cameraDevice) def setCamera(self, cameraDevice): if cameraDevice.isEmpty(): self.camera = QCamera() else: self.camera = QCamera(cameraDevice) self.camera.stateChanged.connect(self.updateCameraState) self.camera.error.connect(self.displayCameraError) self.mediaRecorder = QMediaRecorder(self.camera) self.mediaRecorder.stateChanged.connect(self.updateRecorderState) self.imageCapture = QCameraImageCapture(self.camera) self.mediaRecorder.durationChanged.connect(self.updateRecordTime) self.mediaRecorder.error.connect(self.displayRecorderError) self.mediaRecorder.setMetaData(QMediaMetaData.Title, "Test Title") self.ui.exposureCompensation.valueChanged.connect( self.setExposureCompensation) self.camera.setViewfinder(self.ui.viewfinder) self.updateCameraState(self.camera.state()) self.updateLockStatus(self.camera.lockStatus(), QCamera.UserRequest) self.updateRecorderState(self.mediaRecorder.state()) self.imageCapture.readyForCaptureChanged.connect(self.readyForCapture) self.imageCapture.imageCaptured.connect(self.processCapturedImage) self.imageCapture.imageSaved.connect(self.imageSaved) self.camera.lockStatusChanged.connect(self.updateLockStatus) self.ui.captureWidget.setTabEnabled( 0, self.camera.isCaptureModeSupported(QCamera.CaptureStillImage)) self.ui.captureWidget.setTabEnabled( 1, self.camera.isCaptureModeSupported(QCamera.CaptureVideo)) self.updateCaptureMode() self.camera.start() def keyPressEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.displayViewfinder() self.camera.searchAndLock() event.accept() elif event.key() == Qt.Key_Camera: if self.camera.captureMode() == QCamera.CaptureStillImage: self.takeImage() elif self.mediaRecorder.state() == QMediaRecorder.RecordingState: self.stop() else: self.record() event.accept() else: super(Camera, self).keyPressEvent(event) def keyReleaseEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.camera.unlock() else: super(Camera, self).keyReleaseEvent(event) def updateRecordTime(self): msg = "Recorded %d sec" % (self.mediaRecorder.duration() // 1000) self.ui.statusbar.showMessage(msg) ############################################################################### def detectChars(self, qImg): incomingImage = qImg.convertToFormat(4) width = incomingImage.width() height = incomingImage.height() ptr = incomingImage.bits() ptr.setsize(incomingImage.byteCount()) cvImg = np.array(ptr).reshape(height, width, 4) # Copies the data ###################### centerx = int(cvImg.shape[1] / 2) centery = int(cvImg.shape[0] / 2) half_width = 200 half_height = 100 y = centery - half_height x = centerx - half_width print(type(cvImg)) cvImgCroped = cvImg[y:y + half_height * 2, x:x + half_width * 2] # Crop from x, y, w, h -> 100, 200, 300, 400 cvImgCContinues = np.zeros(cvImgCroped.shape, np.uint8) cvImgCContinues = cvImgCroped.copy() # NOTE: its img[y: y + h, x: x + w] and *not* img[x: x + w, y: y + h] # cvImgCroped = cv2.rectangle(cvImgCroped, # (centerx - half_width, centery - half_height), # (centerx + half_width, centery + half_height), # (0, 0, 255), # 2) ###################### # Convert to RGB for QImage. cvImgCContinues = cv2.cvtColor(cvImgCContinues, cv2.COLOR_BGR2RGB) # cv2.imshow("",cvImgCContinues) # cv2.waitKey(0) height, width, bytesPerComponent = cvImgCContinues.shape bytesPerLine = bytesPerComponent * width self.image = QImage(cvImgCContinues.data, width, height, bytesPerLine, QImage.Format_RGB888) return self.image ############################################################################### def processCapturedImage(self, requestId, img): detectedImage = self.detectChars(img) scaledImage = detectedImage.scaled(self.ui.viewfinder.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.ui.lastImagePreviewLabel.setPixmap(QPixmap.fromImage(scaledImage)) self.displayCapturedImage() QTimer.singleShot(40000, self.displayViewfinder) ############################################################################### def configureCaptureSettings(self): if self.camera.captureMode() == QCamera.CaptureStillImage: self.configureImageSettings() elif self.camera.captureMode() == QCamera.CaptureVideo: self.configureVideoSettings() def configureVideoSettings(self): settingsDialog = VideoSettings(self.mediaRecorder) settingsDialog.setAudioSettings(self.audioSettings) settingsDialog.setVideoSettings(self.videoSettings) settingsDialog.setFormat(self.videoContainerFormat) if settingsDialog.exec_(): self.audioSettings = settingsDialog.audioSettings() self.videoSettings = settingsDialog.videoSettings() self.videoContainerFormat = settingsDialog.format() self.mediaRecorder.setEncodingSettings(self.audioSettings, self.videoSettings, self.videoContainerFormat) def configureImageSettings(self): settingsDialog = ImageSettings(self.imageCapture) settingsDialog.setImageSettings(self.imageSettings) if settingsDialog.exec_(): self.imageSettings = settingsDialog.imageSettings() self.imageCapture.setEncodingSettings(self.imageSettings) def record(self): self.mediaRecorder.record() self.updateRecordTime() def pause(self): self.mediaRecorder.pause() def stop(self): self.mediaRecorder.stop() def setMuted(self, muted): self.mediaRecorder.setMuted(muted) def toggleLock(self): if self.camera.lockStatus() in (QCamera.Searching, QCamera.Locked): self.camera.unlock() elif self.camera.lockStatus() == QCamera.Unlocked: self.camera.searchAndLock() def updateLockStatus(self, status, reason): indicationColor = Qt.black if status == QCamera.Searching: self.ui.statusbar.showMessage("Focusing...") self.ui.lockButton.setText("Focusing...") indicationColor = Qt.yellow elif status == QCamera.Locked: self.ui.lockButton.setText("Unlock") self.ui.statusbar.showMessage("Focused", 2000) indicationColor = Qt.darkGreen elif status == QCamera.Unlocked: self.ui.lockButton.setText("Focus") if reason == QCamera.LockFailed: self.ui.statusbar.showMessage("Focus Failed", 2000) indicationColor = Qt.red palette = self.ui.lockButton.palette() palette.setColor(QPalette.ButtonText, indicationColor) self.ui.lockButton.setPalette(palette) def takeImage(self): self.isCapturingImage = True self.imageCapture.capture() def startCamera(self): self.camera.start() def stopCamera(self): self.camera.stop() def updateCaptureMode(self): tabIndex = self.ui.captureWidget.currentIndex() captureMode = QCamera.CaptureStillImage if tabIndex == 0 else QCamera.CaptureVideo if self.camera.isCaptureModeSupported(captureMode): self.camera.setCaptureMode(captureMode) def updateCameraState(self, state): if state == QCamera.ActiveState: self.ui.actionStartCamera.setEnabled(False) self.ui.actionStopCamera.setEnabled(True) self.ui.captureWidget.setEnabled(True) self.ui.actionSettings.setEnabled(True) elif state in (QCamera.UnloadedState, QCamera.LoadedState): self.ui.actionStartCamera.setEnabled(True) self.ui.actionStopCamera.setEnabled(False) self.ui.captureWidget.setEnabled(False) self.ui.actionSettings.setEnabled(False) def updateRecorderState(self, state): if state == QMediaRecorder.StoppedState: self.ui.recordButton.setEnabled(True) self.ui.pauseButton.setEnabled(True) self.ui.stopButton.setEnabled(False) elif state == QMediaRecorder.PausedState: self.ui.recordButton.setEnabled(True) self.ui.pauseButton.setEnabled(False) self.ui.stopButton.setEnabled(True) elif state == QMediaRecorder.RecordingState: self.ui.recordButton.setEnabled(False) self.ui.pauseButton.setEnabled(True) self.ui.stopButton.setEnabled(True) def setExposureCompensation(self, index): self.camera.exposure().setExposureCompensation(index * 0.5) def displayRecorderError(self): QMessageBox.warning(self, "Capture error", self.mediaRecorder.errorString()) def displayCameraError(self): QMessageBox.warning(self, "Camera error", self.camera.errorString()) def updateCameraDevice(self, action): self.setCamera(action.data()) def displayViewfinder(self): self.ui.stackedWidget.setCurrentIndex(0) def displayCapturedImage(self): self.ui.stackedWidget.setCurrentIndex(1) def readyForCapture(self, ready): self.ui.takeImageButton.setEnabled(ready) def imageSaved(self, id, fileName): self.isCapturingImage = False if self.applicationExiting: self.close() def closeEvent(self, event): if self.isCapturingImage: self.setEnabled(False) self.applicationExiting = True event.ignore() else: event.accept()
class CMainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(CMainWindow, self).__init__(*args, **kwargs) self.oc_camera = None self.l_cameras = QCameraInfo.availableCameras() if len(self.l_cameras) == 0: self.fatal_error("No cameras found!") # Top tool-bar self.oc_toolbar = QtWidgets.QToolBar("Video source selector") self.oc_toolbar.setMovable(False) lbl = QtWidgets.QLabel("Select video source:") self.oc_toolbar.addWidget(lbl) camera_selector = QtWidgets.QComboBox() camera_selector.addItems([ "[ %i ] %s" % (i_idx, oc_cam.description()) for i_idx, oc_cam in enumerate(self.l_cameras)]) camera_selector.currentIndexChanged.connect( self.start_preview ) self.oc_toolbar.addWidget(camera_selector) self.oc_toolbar.layout().setSpacing(5) self.oc_toolbar.layout().setContentsMargins(5, 5, 5, 5) self.addToolBar(self.oc_toolbar) # Central part (video frame) self.oc_viewfinder = QCameraViewfinder() self.setCentralWidget(self.oc_viewfinder) # Bottom status bar self.status = QtWidgets.QStatusBar() self.setStatusBar(self.status) self.setWindowTitle("CamView") self.start_preview(0) def fatal_error(self, s_msg): QtWidgets.QMessageBox.critical(None, "Fatal Error", "%s\nThe application will exit now." % s_msg) sys.exit(-1) def start_preview(self, i_cam_idx): if self.oc_camera is not None: self.oc_camera.stop() del self.oc_camera self.oc_camera = QCamera(self.l_cameras[i_cam_idx]) self.oc_camera.setViewfinder(self.oc_viewfinder) self.oc_camera.setCaptureMode(QCamera.CaptureVideo) self.oc_camera.error.connect(lambda: self.show_error(self.oc_camera.errorString())) self.oc_camera.start() def stop_preview(self): if self.oc_camera is None: return # this is correct logic, no error here self.oc_camera.stop() self.oc_camera.unload() self.oc_camera = None def show_error(self, s): err = QtWidgets.QErrorMessage(self) err.showMessage(s) def closeEvent(self, event): self.stop_preview()
class UiMainWindow(QWidget): """Main UI window of the application. Attributes: ---------- window_width: int Width of the window window_height: int Height of the window button_width: int Width of buttons button_height: int Height of buttons dist: int Distance to the edge of Widgets(Window/Button/Label...) model_selected: bool Shows whether a model is selected or not """ window_height = 650 window_width = 800 button_width = 180 button_height = 50 dist = 30 model_selected = False textbox_height = 25 small_button_width = 100 small_button_height = 30 debug_height = 200 debug_mode = False accepted_download = False current_city = "" def __init__(self, parent) -> None: super().__init__(parent) main_window.setObjectName("main_window") main_window.resize(self.window_width, self.window_height) self.centralwidget = QWidget(main_window) self.centralwidget.setObjectName("centralwidget") self.detector = Detection() self.Box_Stadt = QComboBox(self.centralwidget) self.Box_Stadt.setGeometry( QRect(self.dist, self.dist, self.button_width, self.button_height)) self.Box_Stadt.setObjectName("Box_Stadt") self.Box_Stadt.activated.connect(self.on_dropdown_selected) # dynamic city updates supported_cities_updater = Thread(target=update_dropdown, daemon=True, args=(self.Box_Stadt, )) supported_cities_updater.start() self.Text_City = QLineEdit(self.centralwidget) self.Text_City.setGeometry( QRect(self.dist + self.dist + self.button_width, self.dist + 10, self.button_width, self.textbox_height)) self.Text_City.setObjectName("Text_City") self.Text_City.setToolTip( 'Enter a city you wish to detect sights in that you cannot find in the dropdown on the left after updating.' ) self.Button_City = QPushButton(self.centralwidget) self.Button_City.setGeometry( QRect( int(2.3 * self.dist) + self.button_width + self.button_width, self.dist + 8, self.small_button_width, self.small_button_height)) self.Button_City.setObjectName("Button_City") self.Button_City.clicked.connect(self.request_city) self.Button_Detection = QPushButton(self.centralwidget) self.Button_Detection.setGeometry( QRect( self.window_width - (self.dist + self.button_width), self.window_height - (self.dist + self.button_height + 20), self.button_width, self.button_height, )) self.Button_Detection.setObjectName("Button_Detection") self.Button_Detection.clicked.connect(self.detect_sights) self.Button_Bild = QPushButton(self.centralwidget) self.Button_Bild.setGeometry( QRect( self.dist, self.window_height - (self.dist + self.button_height + 20), self.button_width, self.button_height, )) self.Button_Bild.setObjectName("Button_Bild") self.Button_Bild.clicked.connect(lambda: self.camera_viewfinder.hide()) self.Button_Bild.clicked.connect( lambda: self.Box_Camera_selector.setCurrentIndex(0)) self.Button_Bild.clicked.connect( lambda: self.stacked_widget.setCurrentIndex(0)) self.Button_Bild.clicked.connect(lambda: self.Label_Bild.show()) self.Button_Bild.clicked.connect(self.dragdrop) self.available_cameras = QCameraInfo.availableCameras() self.Box_Camera_selector = QComboBox(self.centralwidget) self.Box_Camera_selector.setGeometry( QRect( self.window_width - (self.dist + self.button_width), self.dist, self.button_width, self.button_height, )) self.Box_Camera_selector.setObjectName("Box_Camera_selector") self.Box_Camera_selector.addItem("") # self.Box_Camera_selector.addItems([camera.description() for camera in self.available_cameras]) self.Box_Camera_selector.addItems([ "Camera " + str(i) + ": " + str(self.available_cameras[i].description()) for i in range(len(self.available_cameras)) ]) self.Box_Camera_selector.currentIndexChanged.connect( self.select_camera) self.stacked_widget = QStackedWidget(self.centralwidget) label_height = (self.window_height - self.dist - self.button_height - self.dist) - (self.dist + self.button_height + self.dist) label_start_y = self.dist + self.button_height + self.dist self.stacked_widget.setGeometry( QRect( self.dist, label_start_y, self.window_width - (self.dist * 2), label_height, )) self.camera_viewfinder = QCameraViewfinder() self.Label_Bild = ImageLabel(self) self.Label_Bild.setGeometry( QRect(0, 0, self.window_width - (self.dist * 2), label_height)) self.checkBoxImprove = QCheckBox( "Help improving SightScan's detection quality", self.centralwidget) self.checkBoxImprove.setObjectName(u"improvement") self.checkBoxImprove.setGeometry(QRect(self.dist, 5, 350, 20)) self.checkBoxImprove.setChecked(False) self.checkBoxImprove.stateChanged.connect(self.set_improve_quality_var) self.checkBox = QCheckBox("Debug", self.centralwidget) self.checkBox.setObjectName(u"checkBox") self.checkBox.setGeometry( QRect(self.window_width - (self.dist + 50), self.window_height - (self.dist + 20), 70, 20)) self.checkBox.setChecked(False) self.checkBox.stateChanged.connect(self.debug_click) # Setup logging fn = "logs/" + datetime.now().strftime( '%d_%m_%Y__%H_%M_%S') + 'log.log' if not os.path.exists("logs"): os.mkdir("logs") f = '%(asctime)s :: %(levelname)s :: %(filename)s :: %(funcName)s :: %(lineno)d :: %(message)s' self.textDebug = QTextEditLogger(self.centralwidget) self.textDebug.setFormatter(logging.Formatter(f)) logging.basicConfig(filename=fn, format=f, level=logging.DEBUG) logging.getLogger().addHandler(self.textDebug) # Log Text Box in GUI self.textDebug.widget.setObjectName(u"textEdit") self.textDebug.widget.setEnabled(False) self.textDebug.widget.setGeometry( QRect(self.dist, self.window_height, self.window_width - 2 * self.dist, self.debug_height - self.dist)) size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.textDebug.widget.sizePolicy().hasHeightForWidth()) self.textDebug.widget.setSizePolicy(size_policy) self.textDebug.widget.setReadOnly(True) self.stacked_widget.addWidget(self.Label_Bild) self.stacked_widget.addWidget(self.camera_viewfinder) main_window.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(main_window) self.menubar.setGeometry(QRect(0, 0, 678, 21)) self.menubar.setObjectName("menubar") main_window.setMenuBar(self.menubar) self.statusbar = QStatusBar(main_window) self.statusbar.setObjectName("statusbar") main_window.setStatusBar(self.statusbar) main_window.setWindowIcon(QIcon(logo_without_text)) self.retranslateUi(main_window) QMetaObject.connectSlotsByName(main_window) def set_improve_quality_var(self): self.improve_checkbox_enabled = self.checkBoxImprove.isChecked() def retranslateUi(self, main_window: QMainWindow) -> None: """Set the text initially for all items. Parameters ---------- main_window: QMainWindow The instance of the prepared application window """ _translate = QCoreApplication.translate main_window.setWindowTitle(_translate(WINDOW, "SightScan")) self.Box_Stadt.addItems(['Choose City'] + initialize_cities()) self.Box_Camera_selector.setItemText( 0, _translate(WINDOW, "Choose Webcam")) self.Button_Detection.setText(_translate(WINDOW, START)) self.Button_Bild.setText(_translate(WINDOW, ENABLE)) self.Button_City.setText(_translate(WINDOW, "Add City")) def on_dropdown_selected(self) -> None: """Shows a pop-up for confirming the download of the selected city.""" city_pretty_print = self.Box_Stadt.currentText() city = self.Box_Stadt.currentText().replace(' ', '_').upper() if city != "CHOOSE_CITY": self.current_city = self.Box_Stadt.currentText() # if no connection to dos if get_supported_cities() == []: latest_version = "couldn't get the latest version" downloaded_version = "couldn't get the downloaded version" print('no connection to dos') # if connection to dos else: downloaded_version = -1 # initialization Path("weights").mkdir(mode=0o700, exist_ok=True) if not os.path.exists("weights/versions.txt"): with open('weights/versions.txt', 'w'): # creating a version file pass with open("weights/versions.txt", "r") as file: for line in file: elements = line.split("=") if elements[0].upper() == city: downloaded_version = int(elements[1]) break latest_version = get_dwh_model_version(city) if downloaded_version == -1: msg = QMessageBox() msg.setWindowTitle("Download City") msg.setWindowIcon(QIcon(logo_without_text)) msg.setText("Do you want to download " + city_pretty_print + "?") msg.setIcon(QMessageBox.Question) msg.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok) msg.setDefaultButton(QMessageBox.Ok) msg.setInformativeText("When downloaded, sights of " + city_pretty_print + " can be detected.") msg.buttonClicked.connect(self.handover_city) msg.exec_() elif latest_version > downloaded_version: update_msg = QMessageBox() update_msg.setWindowTitle("Update available") update_msg.setWindowIcon(QIcon(logo_without_text)) update_msg.setText( "Do you want to download an update for " + city + "?") update_msg.setIcon(QMessageBox.Question) update_msg.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok) update_msg.setDefaultButton(QMessageBox.Ok) update_msg.setInformativeText( "Updated cities can detect sights faster and more accurately. If you choose not to download, the " + "detection will still work.") update_msg.buttonClicked.connect(self.handover_city) update_msg.exec_() if self.accepted_download is True or latest_version == downloaded_version: self.accepted_download = False self.show_download_result() self.model_selected = True else: self.model_selected = False def handover_city(self, button) -> None: """Starts the download of the pre-trained model of the selected city. Parameters ---------- button: Pushed button inside the popup. """ if "OK" in button.text().upper(): city = self.Box_Stadt.currentText().replace(' ', '_').upper() self.model_selected = True model = get_downloaded_model(city) if model is not None: with open("weights/" + city + ".pt", "wb+") as file: file.write(model) self.accepted_download = True elif "CANCEL" in button.text().upper(): self.Box_Stadt.setCurrentIndex(0) def detect_sights(self) -> None: """Starts detection for the dropped image or shown webcam video with the downloaded model and displays the results in the label.""" city = self.Box_Stadt.currentText().replace(' ', '_').upper() print("Detection Status: " + str(self.detector.detection)) if self.model_selected is False: self.show_missing_model_popup() else: # start drag&drop image detection if self.stacked_widget.currentIndex() == 0 and self.Button_Bild.text() == DISABLE and \ self.Label_Bild.image != logo_with_text: print(f"Starting detection of {self.Label_Bild.image}") wipe_prediction_input_images(INPUT_PREDICTION_DIR) shutil.copy2(self.Label_Bild.image, INPUT_PREDICTION_DIR) self.detector.enable_detection() self.detector.detect(self, weights='weights/' + city + '.pt', debug=self.debug_mode) # stop video detection elif self.stacked_widget.currentIndex( ) == 0 and self.Button_Detection.text() == STOP: self.stop_video_detection() time.sleep(2) self.reactivate_cam() # if webcam activated elif self.stacked_widget.currentIndex() == 1: if self.Button_Detection.text() == START: self.Button_Detection.setText( QCoreApplication.translate(WINDOW, STOP)) self.Label_Bild.setStyleSheet(""" """) print("Video Detection Started") self.prep_video_detection() source = self.Box_Camera_selector.currentIndex() self.detector.enable_detection() self.detection_thread = Thread(target=self.detector.detect, args=(self, ), kwargs={ 'weights': 'weights/' + city + '.pt', 'source': str(source - 1), 'image_size': 704, 'debug': self.debug_mode }) self.detection_thread.start() else: print("Drop a File or select a Webcam!") def show_missing_model_popup(self) -> None: # Show Pop Up to choose a city emsg = QMessageBox() emsg.setWindowTitle("No city chosen") emsg.setWindowIcon(QIcon(logo_without_text)) emsg.setText( "You need to choose a city before the detection can start.") emsg.setIcon(QMessageBox.Warning) emsg.setStandardButtons(QMessageBox.Ok) emsg.setDefaultButton(QMessageBox.Ok) emsg.exec_() def show_download_result(self) -> None: # city_pretty_print = self.Box_Stadt.currentText() self.model_selected = True newest_vers_msg = QMessageBox() newest_vers_msg.setWindowTitle("Ready for Detection!") newest_vers_msg.setWindowIcon(QIcon(logo_without_text)) newest_vers_msg.setText("You can start detecting sights in " + self.current_city + "!") newest_vers_msg.setStandardButtons(QMessageBox.Ok) newest_vers_msg.setDefaultButton(QMessageBox.Ok) newest_vers_msg.exec_() def request_city(self) -> None: # Send entered city to dwh and show confirmation popup if the city name is known city_input = self.Text_City.text() city_request = city_input.upper() if len(filter_city(city_input)) == 1: send_city_request(city_request) cmsg = QMessageBox() cmsg.setWindowTitle("Request confirmed") cmsg.setWindowIcon(QIcon(logo_without_text)) cmsg.setText("Your request to add support for " + city_input + " has been sent to our backend.") cmsg.setStandardButtons(QMessageBox.Ok) cmsg.setDefaultButton(QMessageBox.Ok) cmsg.exec_() else: cmsg = QMessageBox() cmsg.setWindowTitle("Unknown city name") cmsg.setWindowIcon(QIcon(logo_without_text)) cmsg.setText( "The typed city name is not known. Please check the spelling.") cmsg.setIcon(QMessageBox.Warning) cmsg.setStandardButtons(QMessageBox.Ok) cmsg.setDefaultButton(QMessageBox.Ok) cmsg.exec_() def dragdrop(self) -> None: """Enables / disables Drag&Drop of images.""" if self.Button_Bild.text() == ENABLE: # stop video detection if active if self.Button_Detection.text() == STOP: self.Button_Detection.setText( QCoreApplication.translate(WINDOW, START)) self.detector.disable_detection() self.Label_Bild.setAcceptDrops(True) self.Label_Bild.setText("\n\n Drop Image here \n\n") self.Label_Bild.setStyleSheet(""" QLabel{ border: 4px dashed #aaa } """) self.Button_Bild.setText( QCoreApplication.translate(WINDOW, DISABLE)) elif self.Button_Bild.text() == DISABLE: self.Label_Bild.setAcceptDrops(False) self.Label_Bild.setText("") self.Label_Bild.setStyleSheet("") self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.Button_Bild.setText(QCoreApplication.translate( WINDOW, ENABLE)) def select_camera(self, i): """Starts the selected camera. If "Choose webcam" is selected, it stops the camera. Parameters ---------- i: Index of the chosen camera. """ self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) if i == 0: self.camera.stop() self.detector.disable_detection() self.Button_Detection.setText( QCoreApplication.translate(WINDOW, START)) self.stacked_widget.setCurrentIndex(0) self.camera_viewfinder.hide() self.Label_Bild.show() time.sleep(2) self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.Label_Bild.setStyleSheet(""" """) else: self.camera_viewfinder.show() self.stacked_widget.setCurrentIndex(1) self.Label_Bild.hide() self.camera = QCamera(self.available_cameras[i - 1]) self.camera.setViewfinder(self.camera_viewfinder) self.camera.error.connect( lambda: self.alert(self.camera.errorString())) self.camera.start() self.Button_Bild.setText(QCoreApplication.translate( WINDOW, ENABLE)) def prep_video_detection(self) -> None: self.camera.stop() self.camera_viewfinder.hide() self.stacked_widget.setCurrentIndex(0) self.Label_Bild.image = loading_image self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.Label_Bild.show() def stop_video_detection(self) -> None: self.Button_Detection.setText(QCoreApplication.translate( WINDOW, START)) self.detector.disable_detection() self.stacked_widget.setCurrentIndex(1) self.Label_Bild.hide() self.camera_viewfinder.show() def debug_click(self, state): self.debug_mode = bool(state) if state: main_window.resize(self.window_width, self.window_height + self.debug_height) self.textDebug.widget.setEnabled(True) else: main_window.resize(self.window_width, self.window_height) self.textDebug.widget.setEnabled(False) def reactivate_cam(self) -> None: self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.camera.start() def close_all(self) -> None: if self.Button_Detection.text() == STOP: self.detector.disable_detection() self.stop_video_detection()
class Camera(QWidget): def __init__(self, parent=None, standalone=False): super(Camera, self).__init__(parent) # This prevents doing unneeded initialization # when QtDesginer loads the plugin. if parent is None and not standalone: return if not multimedia_available: return self.ui = uic.loadUi(os.path.join(WIDGET_PATH, "camera.ui"), self) self.camera = None self.imageCapture = None self.mediaRecorder = None self.isCapturingImage = False self.applicationExiting = False self.imageSettings = QImageEncoderSettings() self.audioSettings = QAudioEncoderSettings() self.videoSettings = QVideoEncoderSettings() self.videoContainerFormat = '' camera_device = QByteArray() videoDevicesGroup = QActionGroup(self) videoDevicesGroup.setExclusive(True) if not QCamera.availableDevices(): self.ui.devicesCombo.addItem("No Device") else: for deviceName in QCamera.availableDevices(): description = QCamera.deviceDescription(deviceName) self.ui.devicesCombo.addItem(description) videoDeviceAction = QAction(description, videoDevicesGroup) videoDeviceAction.setCheckable(True) videoDeviceAction.setData(deviceName) if camera_device.isEmpty(): cameraDevice = deviceName videoDeviceAction.setChecked(True) self.ui.devicesCombo.addAction(videoDeviceAction) videoDevicesGroup.triggered.connect(self.updateCameraDevice) self.ui.captureWidget.currentChanged.connect(self.updateCaptureMode) self.ui.devicesCombo.currentIndexChanged.connect( self.get_device_action) self.ui.lockButton.hide() # Start camera 2s after the UI has loaded QTimer.singleShot(2000, lambda: self.setCamera(camera_device)) def setCamera(self, cameraDevice): try: if cameraDevice.isEmpty(): self.camera = QCamera() else: self.camera = QCamera(cameraDevice) self.camera.stateChanged.connect(self.updateCameraState) self.camera.error.connect(self.displayCameraError) self.mediaRecorder = QMediaRecorder(self.camera) self.mediaRecorder.stateChanged.connect(self.updateRecorderState) self.imageCapture = QCameraImageCapture(self.camera) self.mediaRecorder.durationChanged.connect(self.updateRecordTime) self.mediaRecorder.error.connect(self.displayRecorderError) self.mediaRecorder.setMetaData(QMediaMetaData.Title, "Camera Widget") self.ui.exposureCompensation.valueChanged.connect( self.setExposureCompensation) self.camera.setViewfinder(self.ui.viewfinder) self.updateCameraState(self.camera.state()) self.updateLockStatus(self.camera.lockStatus(), QCamera.UserRequest) self.updateRecorderState(self.mediaRecorder.state()) self.imageCapture.readyForCaptureChanged.connect( self.readyForCapture) self.imageCapture.imageCaptured.connect(self.processCapturedImage) self.imageCapture.imageSaved.connect(self.imageSaved) self.camera.lockStatusChanged.connect(self.updateLockStatus) self.ui.captureWidget.setTabEnabled( 0, self.camera.isCaptureModeSupported(QCamera.CaptureStillImage)) self.ui.captureWidget.setTabEnabled( 1, self.camera.isCaptureModeSupported(QCamera.CaptureVideo)) self.updateCaptureMode() self.camera.start() except: pass def keyPressEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.displayViewfinder() self.camera.searchAndLock() event.accept() elif event.key() == Qt.Key_Camera: if self.camera.captureMode() == QCamera.CaptureStillImage: self.takeImage() elif self.mediaRecorder.state() == QMediaRecorder.RecordingState: self.stop() else: self.record() event.accept() else: super(Camera, self).keyPressEvent(event) def keyReleaseEvent(self, event): if event.isAutoRepeat(): return if event.key() == Qt.Key_CameraFocus: self.camera.unlock() else: super(Camera, self).keyReleaseEvent(event) def updateRecordTime(self): msg = "Recorded {} sec".format(self.mediaRecorder.duration()) self.ui.timeLabel.text = msg print(msg) def processCapturedImage(self, requestId, img): scaledImage = img.scaled(self.ui.viewfinder.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.ui.lastImagePreviewLabel.setPixmap(QPixmap.fromImage(scaledImage)) self.displayCapturedImage() QTimer.singleShot(4000, self.displayViewfinder) def configureSettings(self): settings_dialog = Settings(self.mediaRecorder, self.imageCapture) settings_dialog.setImageSettings(self.imageSettings) settings_dialog.setAudioSettings(self.audioSettings) settings_dialog.setVideoSettings(self.videoSettings) settings_dialog.setFormat(self.videoContainerFormat) # settings_dialog.setStreamingSettings(self.streamingSettings) if settings_dialog.exec_(): self.imageSettings = settings_dialog.imageSettings() self.audioSettings = settings_dialog.audioSettings() self.videoSettings = settings_dialog.videoSettings() self.videoContainerFormat = settings_dialog.format() self.imageCapture.setEncodingSettings(self.imageSettings) self.mediaRecorder.setEncodingSettings(self.audioSettings, self.videoSettings, self.videoContainerFormat) def record(self): self.mediaRecorder.record() self.updateRecordTime() def pause(self): self.mediaRecorder.pause() def stop(self): self.mediaRecorder.stop() def setMuted(self, muted): self.mediaRecorder.setMuted(muted) def toggleLock(self): if self.camera.lockStatus() in (QCamera.Searching, QCamera.Locked): self.camera.unlock() elif self.camera.lockStatus() == QCamera.Unlocked: self.camera.searchAndLock() def updateLockStatus(self, status, reason): indicationColor = Qt.black if status == QCamera.Searching: self.ui.statusbar.showMessage("Focusing...") self.ui.lockButton.setText("Focusing...") indicationColor = Qt.yellow elif status == QCamera.Locked: self.ui.lockButton.setText("Unlock") self.ui.statusbar.showMessage("Focused", 2000) indicationColor = Qt.darkGreen elif status == QCamera.Unlocked: self.ui.lockButton.setText("Focus") if reason == QCamera.LockFailed: self.ui.statusbar.showMessage("Focus Failed", 2000) indicationColor = Qt.red palette = self.ui.lockButton.palette() palette.setColor(QPalette.ButtonText, indicationColor) self.ui.lockButton.setPalette(palette) def takeImage(self): self.isCapturingImage = True self.imageCapture.capture() def startCamera(self): self.camera.start() def stopCamera(self): self.camera.stop() def updateCaptureMode(self): tabIndex = self.ui.captureWidget.currentIndex() captureMode = QCamera.CaptureStillImage if tabIndex == 0 else QCamera.CaptureVideo if self.camera.isCaptureModeSupported(captureMode): self.camera.setCaptureMode(captureMode) def updateCameraState(self, state): if state == QCamera.ActiveState: self.ui.actionStartCamera.setEnabled(False) self.ui.actionStopCamera.setEnabled(True) self.ui.captureWidget.setEnabled(True) self.ui.actionSettings.setEnabled(True) elif state in (QCamera.UnloadedState, QCamera.LoadedState): self.ui.actionStartCamera.setEnabled(True) self.ui.actionStopCamera.setEnabled(False) self.ui.captureWidget.setEnabled(False) self.ui.actionSettings.setEnabled(False) def updateRecorderState(self, state): if state == QMediaRecorder.StoppedState: self.ui.recordButton.setEnabled(True) self.ui.pauseButton.setEnabled(True) self.ui.stopButton.setEnabled(False) elif state == QMediaRecorder.PausedState: self.ui.recordButton.setEnabled(True) self.ui.pauseButton.setEnabled(False) self.ui.stopButton.setEnabled(True) elif state == QMediaRecorder.RecordingState: self.ui.recordButton.setEnabled(False) self.ui.pauseButton.setEnabled(True) self.ui.stopButton.setEnabled(True) def setExposureCompensation(self, index): self.camera.exposure().setExposureCompensation(index * 0.5) def displayRecorderError(self): QMessageBox.warning(self, "Capture error", self.mediaRecorder.errorString()) def displayCameraError(self): QMessageBox.warning(self, "Camera error", self.camera.errorString()) def get_device_action(self, index): self.ui.devicesCombo.actions()[index].trigger() def updateCameraDevice(self, action): self.setCamera(action.data()) def displayViewfinder(self): self.ui.stackedWidget.setCurrentIndex(0) def displayCapturedImage(self): self.ui.stackedWidget.setCurrentIndex(1) def readyForCapture(self, ready): self.ui.takeImageButton.setEnabled(ready) def imageSaved(self, id, fileName): self.isCapturingImage = False if self.applicationExiting: self.close() def closeEvent(self, event): if self.isCapturingImage: self.setEnabled(False) self.applicationExiting = True event.ignore() else: event.accept()