#########################################################################
# MoilApp (Applications for sophisticated fisheye image processing) #
# Written by Haryanto (haryanto@o3635.mcut.edu.tw) #
# Based on Moil-Lab (Ming Chi University of Technology) #
#########################################################################
import os
import cv2
import datetime
import webbrowser
import numpy as np
from help import Help
from moilutils import ResourceIcon
from functools import partial
from PyQt5 import QtWidgets, QtGui, QtCore
from moilutils import MoilUtils
from plugin_controller import PluginController
from Ui_Moilapp import Ui_MainWindow
from panorama import Panorama
from anypoint import Anypoint
from reCenter import RecenterImage
from control_view import ManipulateView
from event_controller import MouseEvent
from moilutils import VideoController
[docs]
class Controller(Ui_MainWindow):
resized = QtCore.pyqtSignal()
def __init__(self, parent):
"""
Args:
parent ():
"""
super().__init__(parent)
self.comboBox_cam_type = None
self.parent = parent
self.setupUi(self.parent)
self.rs = ResourceIcon()
self.open_plugin = False
self.image = None
self.cap = None
self.cam = False
self.record = False
self.video_writer = None
self.videoDir = None
self.moildev = None
self.recImage = None
self.normal_view = True
self.panorama_view = False
self.anypoint_view = False
self.axis_controller = False
self.dir_save = None
self.posVid = []
self.mapX = None
self.mapY = None
self.mapX_pano = None
self.mapY_pano = None
self.zoom_area = False
self.type_camera = None
self.num = 0
self.pos_x = 0
self.w = 0
self.h = 0
self.point = None
self.result_image = None
self.easySpin = False
self.width_original_image = 300
self.width_result_image = 1080
self.angle = 0
self.dialogHelp = QtWidgets.QDialog()
self.winHelp = Help(self, self.dialogHelp)
self.video_controller = VideoController(self)
self.panorama = Panorama(self)
self.anypoint = Anypoint(self)
self.recenter = RecenterImage(self)
self.control_mouse = MouseEvent(self)
self.manipulate = ManipulateView(self)
self.frameVideoController.hide()
self.frame_panorama.hide()
self.frame_navigator.hide()
self.buttonBack.hide()
self.buttonRecenter.hide()
self.labelrecenterTitle.hide()
self.frameRecenter.hide()
self.control_plugin = PluginController(self)
self.connect_event()
[docs]
def connect_event(self):
"""
Connect every event on user interface like button event, mouse event
and etc to the function processing.
"""
self.parent.closeEvent = self.closeEvent
self.parent.resizeEvent = self.resizeEvent
# action from menubar menu file
self.actionLoad_Image.triggered.connect(self.open_image)
self.actionLoad_Video.triggered.connect(self.onclick_load_video)
self.actionOpen_Cam.triggered.connect(self.open_camera)
self.actionCamera_Parameters.triggered.connect(MoilUtils.parametersForm)
self.actionRecord_video.triggered.connect(self.actionRecordVideo)
self.actionSave_Image.triggered.connect(self.save_image)
self.actionExit.triggered.connect(self.onclick_exit)
# action from menubar menu view
self.actionRotateLeft.triggered.connect(self.manipulate.rotate_left)
self.actionRotateRight.triggered.connect(self.manipulate.rotate_right)
self.actionZoomIn.triggered.connect(self.manipulate.zoom_in)
self.actionZoomOut.triggered.connect(self.manipulate.zoom_out)
# action from menubar menu Window
self.actionMaximize.triggered.connect(self.maximize_view)
self.actionMinimize.triggered.connect(self.minimize_view)
# action from menubar menu apps
self.actionHelpPlugins.triggered.connect(self.winHelp.help_plugin)
# action from menubar menu help
self.actionAbout_Apps.triggered.connect(self.onclick_help_moil)
self.actionAbout_Us.triggered.connect(self.winHelp.about_us)
self.action_accessibility.triggered.connect(self.onclick_accessibility)
self.actionReleaseNote.triggered.connect(self.onclickReleaseNote)
self.actionCheckUpdate.triggered.connect(self.checkUpdate)
# ++++++ Normal view ++++++
self.btn_normal.clicked.connect(self.onclick_view_normal)
# +++++ anypoint View +++++
self.btn_anypoint.clicked.connect(self.anypoint.process_to_anypoint)
self.btn_Up_View.clicked.connect(self.anypoint.up)
self.btn_Right_view.clicked.connect(self.anypoint.right)
self.btn_left_view.clicked.connect(self.anypoint.left)
self.btn_center_view.clicked.connect(self.anypoint.center)
self.btn_Down_view.clicked.connect(self.anypoint.down)
self.radio_btn_mode_1.clicked.connect(self.anypoint.anypoint_mode_1)
self.radio_btn_mode_2.clicked.connect(self.anypoint.anypoint_mode_2)
self.lineedit_alpha_2.editingFinished.connect(self.anypoint.set_param_any)
self.lineedit_beta_2.editingFinished.connect(self.anypoint.set_param_any)
self.anypoint_zoom_2.editingFinished.connect(self.anypoint.set_param_any)
# +++++ panorama View +++++
self.btn_panorama.clicked.connect(self.panorama.process_to_panorama)
self.max_pano.valueChanged.connect(self.panorama.change_panorama_fov)
self.min_pano.valueChanged.connect(self.panorama.change_panorama_fov)
# +++ recenter view ++++
self.buttonRecenter.clicked.connect(self.onclickRecenter)
self.setIcx.valueChanged.connect(self.recenter.positionCoorX)
self.setIcy.valueChanged.connect(self.recenter.positionCoorY)
# connect button to function
self.btn_Open_Image.clicked.connect(self.open_image)
self.btn_Open_Video.clicked.connect(self.onclick_load_video)
self.btn_Open_Cam.clicked.connect(self.open_camera)
self.btn_Save_Image.clicked.connect(self.save_image)
# media player controller
self.btn_Record_video.clicked.connect(self.buttonRecordVideo)
self.btn_play_pouse.clicked.connect(partial(self.video_controller.playPauseVideo, self.btn_play_pouse))
self.btn_stop_video.clicked.connect(self.video_controller.stopVideo)
self.btn_prev_video.clicked.connect(self.video_controller.rewindVideo)
self.btn_skip_video.clicked.connect(self.video_controller.forwardVideo)
self.slider_Video.valueChanged.connect(self.video_controller.sliderController)
# control view
self.btn_Rotate_Left.clicked.connect(self.manipulate.rotate_left)
self.btn_Rotate_Right.clicked.connect(self.manipulate.rotate_right)
self.btn_Zoom_in.clicked.connect(self.manipulate.zoom_in)
self.btn_Zoom_out.clicked.connect(self.manipulate.zoom_out)
# mouse event controller
self.label_Original_Image.mouseDoubleClickEvent = self.control_mouse.mouseDoubleclick_event
self.label_Result_Image.mouseDoubleClickEvent = self.control_mouse.mouseDoubleclick_event
self.label_Original_Image.mousePressEvent = self.control_mouse.mouse_event
self.label_Result_Image.mousePressEvent = self.control_mouse.mouse_result_press
self.label_Original_Image.wheelEvent = self.control_mouse.mouse_wheelEvent_ori_label
self.label_Result_Image.wheelEvent = self.control_mouse.mouse_wheelEvent
self.label_Result_Image.mouseReleaseEvent = self.control_mouse.mouse_release_event
self.label_Original_Image.mouseMoveEvent = self.control_mouse.mouseMovedOriImage
self.label_Result_Image.mouseMoveEvent = self.control_mouse.mouseMoveEvent
# others
self.btnAboutUs.clicked.connect(self.winHelp.about_us)
self.btnHelpMoil.clicked.connect(self.onclick_help_moil)
self.btn_clear.clicked.connect(self.onclick_clear)
self.listWidget.currentItemChanged.connect(self.saved_image_activated)
self.comboBox_zoom.activated.connect(self.combo_percentage_zoom)
self.button_menu.clicked.connect(self.control_frame_view_button)
self.buttonBack.clicked.connect(self.showToWindow)
[docs]
def onclick_clear(self):
if self.cam:
self.video_controller.stopVideo()
self.cap.release()
self.frameVideoController.hide()
self.label_Result_Image.clear()
self.label_Result_Image.setMaximumSize(QtCore.QSize(1080, 810))
self.label_Result_Image.setMinimumSize(QtCore.QSize(1080, 810))
self.label_Original_Image.setMinimumSize(QtCore.QSize(266, 200))
self.label_Original_Image.clear()
self.reset_mode_view()
self.comboBox_zoom.removeItem(8)
self.comboBox_zoom.setCurrentIndex(0)
self.label_Application.setText("MoilApp")
self.parent.setWindowTitle("MoilApp")
self.buttonBack.hide()
self.frameRecenter.hide()
self.buttonRecenter.hide()
self.image = None
self.recImage = None
[docs]
def open_image(self):
"""
Open Dialog to search the file image from directory. This function also will read the comment from
metadata image.
"""
filename = MoilUtils.selectFile(self.parent, "Image Files",
"../SourceImage", "(*.jpeg *.jpg *.png *.gif *.bmg)")
if filename:
self.reset_mode_view()
if self.cam:
self.video_controller.stopVideo()
self.cap.release()
self.frameVideoController.hide()
typeCam = MoilUtils.read_camera_type(filename)
if typeCam == "" or typeCam == None:
self.type_camera = MoilUtils.selectCameraType()
MoilUtils.write_camera_type(filename, self.type_camera)
else:
self.type_camera = typeCam
if self.type_camera is not None:
self.updateLabel(filename)
self.image = MoilUtils.readImage(filename)
self.h, self.w = self.image.shape[:2]
self.moildev = MoilUtils.connectToMoildev(self.type_camera)
self.buttonRecenter.setChecked(False)
self.buttonRecenter.setStyleSheet(
"QPushButton{\n"
" border-color: #71D1BA;\n"
" border-width: 2px; \n"
" border-style: solid;\n"
" border-radius: 5px;\n"
" background-color : rgb(238, 238, 236); }\n")
self.showToWindow()
self.cam = False
[docs]
def onclick_load_video(self):
"""
Open Dialog to search video file from Directory. after you select the video file, it will show the prompt
to select the type of camera.
"""
video_source = MoilUtils.selectFile(self.parent,
"Select Video Files",
"../",
"Video Files (*.mp4 *.avi *.mpg *.gif *.mov)")
if video_source:
self.reset_mode_view()
self.type_camera = MoilUtils.selectCameraType()
self.easySpin = False
if self.type_camera is not None:
self.updateLabel(video_source)
self.running_video(video_source)
[docs]
def open_camera(self):
"""
open the camera from the available source in the system,
this function provide 2 source namely USB cam and Streaming cam from Raspberry pi.
"""
self.reset_mode_view()
camera_source = MoilUtils.selectCameraSource()
if camera_source is not None:
self.type_camera = MoilUtils.selectCameraType()
if self.type_camera is not None:
self.updateLabel()
if self.type_camera == "narl_fisheye":
self.easySpin = True
self.running_video(camera_source, True)
else:
self.running_video(camera_source)
self.easySpin = False
[docs]
def running_video(self, video_source, easySpin = False):
"""
Open Video following the source given.
Args:
video_source (): the source of media, can be camera and video file.
"""
self.frameVideoController.show()
if easySpin:
try:
import EasyPySpin
self.cap = EasyPySpin.VideoCapture(video_source)
self.cap.set(cv2.CAP_PROP_EXPOSURE, -1) # -1 sets exposure_time to auto
self.cap.set(cv2.CAP_PROP_GAIN, -1) # -1 sets gain to auto
print('\nModule was installed')
except ImportError:
print('\nThere was no such module installed')
QtWidgets.QMessageBox.warning(None, "Warning !!", "The Module was not Installed. \n\n"
"Please install the library following \n"
"the document provided.")
else:
self.cap = cv2.VideoCapture(video_source)
if self.type_camera == "leo_fisheye":
self.cap.set(3, 1920)
self.cap.set(4, 1080)
success, self.image = self.cap.read()
if success:
self.h, self.w = self.image.shape[:2]
self.moildev = MoilUtils.connectToMoildev(self.type_camera)
self.cam = True
self.buttonRecenter.setChecked(False)
self.buttonRecenter.setStyleSheet(
"QPushButton{\n"
" border-color: #71D1BA;\n"
" border-width: 2px; \n"
" border-style: solid;\n"
" border-radius: 5px;\n"
" background-color : rgb(238, 238, 236); }\n")
self.video_controller.nextFrame()
else:
QtWidgets.QMessageBox.information(self.parent, "Information", "No source camera founded !!!")
[docs]
def onclick_view_normal(self):
"""
Showing the original image into Label frame in UI.
"""
if self.image is not None:
self.buttonRecenter.setChecked(False)
self.buttonRecenter.setStyleSheet(
"QPushButton{\n"
" border-color: #71D1BA;\n"
" border-width: 2px; \n"
" border-style: solid;\n"
" border-radius: 5px;\n"
" background-color : rgb(238, 238, 236); }\n")
self.reset_mode_view()
self.normal_view = True
self.panorama_view = False
self.anypoint_view = False
self.angle = 0
self.showToWindow()
self.frame_navigator.hide()
self.frame_panorama.hide()
self.show_percentage()
self.status_alpha.setText("Alpha: 0")
self.status_beta.setText("Beta: 0")
[docs]
def showToWindow(self):
"""
Showing the processing result image into the frame UI.
"""
# _, img = self.cap.read()
# if not _:
# QtWidgets.QMessageBox.information(None, "Test", "Finishhhh")
self.zoom_area = False
self.buttonBack.hide()
radius = 6 if self.h < 800 else 10
if self.normal_view:
self.frameRecenter.hide()
self.labelrecenterTitle.hide()
self.buttonRecenter.show()
if self.buttonRecenter.isChecked():
self.labelMin.hide()
self.labelMax.hide()
self.min_pano.hide()
self.max_pano.hide()
self.labelIcx.show()
self.labelIcy.show()
self.setIcx.show()
self.setIcy.show()
self.recImage = self.recenter.returnImage()
resImage = self.recImage
self.frame_panorama.setGeometry(QtCore.QRect(5, 50, 180, 80))
else:
resImage = self.image
self.point = (round(self.moildev.icx()), round(self.moildev.icy()))
self.frame_panorama.hide()
image = MoilUtils.drawPoint(self.image.copy(), self.point, radius)
MoilUtils.showImageToLabel(self.label_Original_Image,
image,
self.width_original_image)
MoilUtils.showImageToLabel(self.label_Result_Image,
resImage,
self.width_result_image, self.angle, plusIcon=True)
elif self.panorama_view:
self.buttonRecenter.show()
mapX = np.load(
'./maps_pano/mapX.npy')
mapY = np.load(
'./maps_pano/mapY.npy')
# rho = self.panorama.rho
if self.buttonRecenter.isChecked():
self.frameRecenter.show()
self.labelrecenterTitle.show()
self.labelIcx.show()
self.labelIcy.show()
self.setIcx.show()
self.setIcy.show()
self.labelMin.show()
self.labelMax.show()
self.min_pano.show()
self.max_pano.show()
self.frame_panorama.setGeometry(QtCore.QRect(5, 50, 180, 145))
self.recImage = self.recenter.returnImage()
resImage = self.recImage
# res = MoilUtils.drawPolygon(resImage.copy(), mapX, mapY)
MoilUtils.showImageToLabel(self.labelRecenter,
resImage,
self.width_original_image, plusIcon=True)
image = MoilUtils.drawPoint(self.image.copy(), self.point, radius)
MoilUtils.showImageToLabel(self.label_Original_Image,
image,
self.width_original_image)
else:
self.frameRecenter.hide()
self.labelrecenterTitle.hide()
self.labelIcx.hide()
self.labelIcy.hide()
self.setIcx.hide()
self.setIcy.hide()
self.labelMin.show()
self.labelMax.show()
self.min_pano.show()
self.max_pano.show()
self.frame_panorama.setGeometry(QtCore.QRect(5, 50, 180, 80))
resImage = self.image.copy()
self.point = (round(self.moildev.icx()), round(self.moildev.icy()))
# self.result_image = self.result_image[round(rho):self.h, 0:self.w]
# print(self.result_image)
# image = MoilUtils.drawPolygon(self.image.copy(), mapX, mapY)
image = MoilUtils.drawPoint(self.image.copy(), self.point, radius)
MoilUtils.showImageToLabel(self.label_Original_Image,
image,
self.width_original_image)
self.result_image = MoilUtils.remap(resImage, mapX, mapY)
MoilUtils.showImageToLabel(self.label_Result_Image,
self.result_image,
self.width_result_image, self.angle)
else:
self.buttonRecenter.hide()
self.frameRecenter.hide()
self.labelrecenterTitle.hide()
image = MoilUtils.drawPolygon(self.image.copy(), self.mapX, self.mapY)
image = MoilUtils.drawPoint(image, self.point, radius)
self.result_image = MoilUtils.remap(self.image, self.mapX, self.mapY)
result = MoilUtils.drawLine(self.result_image.copy())
MoilUtils.showImageToLabel(self.label_Result_Image,
result,
self.width_result_image, self.angle, plusIcon=True)
MoilUtils.showImageToLabel(self.label_Original_Image,
image,
self.width_original_image)
self.show_percentage()
[docs]
def save_image(self):
"""
Save image into local directory, it can save original image or
result image from panorama or anypoint processing.
"""
if self.image is not None:
image = self.image if self.normal_view else self.result_image
if self.dir_save is None or self.dir_save == "":
self.video_controller.pauseVideo()
self.dir_save = MoilUtils.selectDirectory(self)
if self.dir_save:
self.name_saved = MoilUtils.saveImage(image, self.dir_save, self.type_camera)
self.addWidget(image)
QtWidgets.QMessageBox.information(
self.parent, "Information", "Image saved !!\n\nLoc @: " + self.dir_save)
[docs]
def saved_image_activated(self):
"""
Function that for connect with the event in list widget to reopen the image.
"""
filename = self.dir_save + "/" + self.listWidget.currentItem().text()
posFrame = self.posVid[self.listWidget.currentRow()]
self.type_camera = MoilUtils.read_camera_type(filename)
if self.cam:
self.video_controller.pauseVideo()
self.reset_mode_view()
self.image = MoilUtils.readImage(filename)
self.h, self.w = self.image.shape[:2]
self.cap.set(cv2.CAP_PROP_POS_FRAMES, posFrame)
self.video_controller.nextFrame()
if self.listWidget.count() == 1:
self.listWidget.selectionModel().reset()
[docs]
def cropImage(self, rect):
image = self.convertCv2ToQimage(self.image.copy()) if self.result_image is None \
else self.convertCv2ToQimage(self.result_image.copy())
height = MoilUtils.calculateHeight(self.image, self.width_result_image)
ratio_x = self.w / self.width_result_image
ratio_y = self.h / height
x = rect.x() * ratio_x
y = rect.y() * ratio_y
width = rect.width() * ratio_x
height = rect.height() * ratio_y
rect = QtCore.QRect(x, y, width, height)
croppedImage = image.copy(rect)
point_1 = (round(x), round(y))
point_2 = (round(x + width), round(y + height))
ori_image = self.image.copy() if self.normal_view else self.result_image.copy()
image = MoilUtils.drawRectangle(ori_image, point_1, point_2)
return image, self.convertQImageToMat(croppedImage)
[docs]
@classmethod
def convertCv2ToQimage(cls, im):
qim = QtGui.QImage()
if im is None:
return qim
if im.dtype == np.uint8:
if len(im.shape) == 2:
qim = QtGui.QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QtGui.QImage.Format_Indexed8)
qim.setColorTable([QtGui.qRgb(i, i, i) for i in range(256)])
elif len(im.shape) == 3:
if im.shape[2] == 3:
qim = QtGui.QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QtGui.QImage.Format_RGB888)
elif im.shape[2] == 4:
qim = QtGui.QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QtGui.QImage.Format_ARGB32)
return qim
[docs]
@classmethod
def convertQImageToMat(cls, incomingImage):
""" Converts a QImage into an opencv MAT format """
incomingImage = incomingImage.convertToFormat(4)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.bits()
ptr.setsize(incomingImage.byteCount())
arr = np.array(ptr).reshape(height, width, 4) # Copies the data
return cv2.cvtColor(arr, cv2.COLOR_BGR2RGB)
[docs]
def show_percentage(self):
count = self.comboBox_zoom.count()
if count == 8:
self.comboBox_zoom.addItem("")
self.comboBox_zoom.setCurrentIndex(8)
size = round((self.width_result_image / self.w) * 100)
self.comboBox_zoom.setItemText(8, (str(size) + "%"))
[docs]
def combo_percentage_zoom(self):
if self.image is not None:
self.comboBox_zoom.removeItem(8)
percent = self.comboBox_zoom.currentText()
percent = int(percent.replace("%", ""))
self.width_result_image = round((self.w * percent) / 100)
self.showToWindow()
[docs]
def reset_mode_view(self):
"""
Update the properties' widget_controller when you reset.
"""
self.result_image = None
self.width_result_image = 1080
self.normal_view = True
self.anypoint.resetAlphaBeta()
self.btn_Record_video.setChecked(False)
self.frame_navigator.hide()
self.frame_panorama.hide()
[docs]
def maximize_view(self):
"""
Control the widget on user interface to make possible in maximum size.
"""
self.label_saved_image.hide()
self.listWidget.hide()
self.frame_original_image.hide()
self.frame_help.hide()
self.frame_feature.hide()
self.frame_2.hide()
self.frame_Open_Source.hide()
self.frame_rotate.hide()
self.frame_zoom.hide()
self.frame_save.hide()
self.label_Application.hide()
self.frame_13.hide()
self.frame_16.hide()
self.frame_17.hide()
self.frame_18.hide()
self.labelOrginalTitle.hide()
self.label_time_recent.hide()
self.slider_Video.hide()
self.label_time_end.hide()
self.frame_apps.hide()
self.frame_clear.hide()
self.labelrecenterTitle.hide()
self.frameRecenter.hide()
self.statusbar.hide()
[docs]
def minimize_view(self):
"""
Control the widget on user interface to make possible in minimum size.
"""
self.labelOrginalTitle.show()
self.label_saved_image.show()
self.listWidget.show()
self.frame_original_image.show()
self.frame_help.show()
self.frame_feature.show()
self.frame_2.show()
self.frame_Open_Source.show()
self.frame_rotate.show()
self.frame_zoom.show()
self.frame_save.show()
self.label_Application.show()
self.frame_13.show()
self.frame_16.show()
self.frame_17.show()
self.frame_18.show()
self.label_time_recent.show()
self.slider_Video.show()
self.label_time_end.show()
self.frame_apps.show()
self.frame_clear.show()
self.statusbar.show()
self.labelOrginalTitle.show()
if self.buttonRecenter.isChecked():
if self.panorama_view:
self.labelrecenterTitle.show()
self.frameRecenter.show()
[docs]
def actionRecordVideo(self):
"""
Create video writer to save video.
"""
if self.image is None:
self.actionRecord_video.setChecked(False)
else:
if self.cam:
if self.actionRecord_video.isChecked():
if self.video_controller.play:
self.video_controller.pauseVideo()
if self.videoDir is None or self.videoDir == "":
self.videoDir = MoilUtils.selectDirectory()
if self.videoDir:
ss = datetime.datetime.now().strftime("%m%d%H_%M%S")
frame_width = int(self.cap.get(3))
frame_height = int(self.cap.get(4))
filename = "Recorded" # if self.parent.normal_view else "result"
name = self.videoDir + "/" + filename + "_" + str(ss) + ".avi"
answer = QtWidgets.QMessageBox.information(
self.parent,
"Information",
" Start Record Video !!",
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if answer == QtWidgets.QMessageBox.Yes:
self.video_controller.playVideo()
self.video_writer = cv2.VideoWriter(
name, cv2.VideoWriter_fourcc(
*'XVID'), self.video_controller.fps, (frame_width, frame_height))
os.makedirs(os.path.dirname(name), exist_ok=True)
self.btn_Record_video.setChecked(True)
self.btn_Record_video.setIcon(
QtGui.QIcon(QtGui.QPixmap.fromImage(self.rs.iconRecording())))
self.actionRecord_video.setIcon(
QtGui.QIcon(QtGui.QPixmap.fromImage(self.rs.iconRecording())))
self.record = True
if answer == QtWidgets.QMessageBox.No:
self.actionRecord_video.setChecked(False)
self.record = False
else:
self.videoDir = None
self.actionRecord_video.setChecked(False)
else:
if self.videoDir:
self.video_controller.timer.stop()
self.btn_play_pouse.setIcon(
QtGui.QIcon(QtGui.QPixmap.fromImage(self.rs.iconPlay())))
QtWidgets.QMessageBox.information(
self.parent,
"Information",
"Video saved !!\n\nLoc: " +
self.videoDir)
self.video_writer = None
self.video_controller.play = False
self.record = False
self.actionRecord_video.setChecked(False)
self.btn_Record_video.setChecked(False)
self.btn_Record_video.setIcon(
QtGui.QIcon(QtGui.QPixmap.fromImage(self.rs.iconRecord())))
self.actionRecord_video.setIcon(
QtGui.QIcon(QtGui.QPixmap.fromImage(self.rs.iconRecord())))
[docs]
def onclickRecenter(self):
if self.buttonRecenter.isChecked():
self.buttonRecenter.setStyleSheet(
"QPushButton{\n"
" border-color: #71D1BA;\n"
" border-width: 2px; \n"
" border-style: solid;\n"
" border-radius: 5px;\n"
" background-color : #81AED1; }\n")
self.recenter.onclickRecenter()
self.frame_panorama.show()
# self.checkAuto.show()
else:
self.buttonRecenter.setStyleSheet(
"QPushButton{\n"
" border-color: #71D1BA;\n"
" border-width: 2px; \n"
" border-style: solid;\n"
" border-radius: 5px;\n"
" background-color : rgb(238, 238, 236); }\n")
self.showToWindow()
self.recImage = None
[docs]
def onclickReleaseNote(self):
"""
Showing the message box to show help information obout this application.
"""
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Release Note")
msgbox.setText(
"New features MoilApp Version 3.2*\n\n"
"There are many updates in this version, "
"which can improve the results of processing fisheye camera images, including: \n\n"
"1. Shortcuts for every process and button work well, show on accessibility in menu help\n"
"2. Added redo function during zoom area\n"
"3. Added Menubar View for manipulate view image\n"
"4. Fix bug in zoom area\n"
"5. Record video using action or button\n"
"\nMore Documentation about MoilApp, visit: \nhttps://oil-mcut.educationhost.cloud/moilapp/\n")
msgbox.exec()
[docs]
@classmethod
def checkUpdate(cls):
webbrowser.open('https://github.com/MoilOrg/MoilApp')
[docs]
def onclick_accessibility(self):
"""
Open prompt for accessibility MoilApp
Returns:
"""
QtWidgets.QMessageBox.information(
self.parent, "Accessibility", "MoilApp Accessibility\n\n"
"Information !!\n"
"Crtl + I\t: Open Image\n"
"Ctrl + V\t: Open Video\n"
"Ctrl + C\t: Open cam\n"
"Ctrl + P\t: Open Camera parameters form\n"
"Ctrl + R\t: Record Video\n"
"Ctrl + S\t: Save image\n"
"Ctrl + Q\t: Exit apps\n"
"+ \t: Zoom In\n"
"- \t: Zoom Out\n"
"F11 \t: Maximized window\n"
"Esc \t: Minimized window\n"
"Ctrl + Left\t: Backward video in 5 seconds\n"
"Space\t: play/pause video\n"
"0 \t: Stop video\n"
"Ctrl + Right\t: Forward video in 5 seconds\n"
"Up\t: Up View\n"
"Right\t: Right view\n"
"Left\t: Left view\n"
"Down\t: Down View\n"
"Ctrl + Shift + /\t:show help\n"
"Alt + Shift + A\t:Show Accessibility\n\n")
[docs]
def onclick_help(self):
"""
Showing the message box to show help information obout this application.
"""
self.winHelp.help_moilApp()
[docs]
def onclick_help_moil(self):
self.dialogHelp.show()
[docs]
def updateLabel(self, filename=None):
if filename is None:
self.parent.setWindowTitle("MoilApp - " + self.type_camera)
else:
self.parent.setWindowTitle("MoilApp - " + filename)
self.label_Application.setText("Camera: " + self.type_camera)
[docs]
def onclick_exit(self):
"""
Returns:
"""
self.parent.close()
[docs]
def closeEvent(self, event):
"""
Control the close event by ask yes or no.
Args:
event ():
Returns:
"""
if self.cam:
self.video_controller.pauseVideo()
reply = QtWidgets.QMessageBox.question(
self.parent,
'Message',
"Are you sure to quit?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
if self.open_plugin:
for i in range(len(self.control_plugin.plugins.name_application)):
self.control_plugin.plugin_win[i].close()
if self.cam:
self.cap.release()
event.accept()
else:
event.ignore()