Source code for plugins.Thread_inspection.main

# MoilApp with thread inspection application
# Writer: Haryanto
# Moil (Ming Chi University of Technology)
import cv2
import json
import numpy as np
import exif_lib
import datetime
from Moildev import Moildev
from Moildev import draw_polygon
from base_plugin import Plugin

from .widgets.Ui_MainWindow import *
from .process_image.anypoint import AnypointView
from .process_image.panorama import PanoramaView
from .controller.video_controller import VideoController
from .controller.select_source_camera import OpenCameraSource
from .help.help import open_information_moildev, help_moildev_apps, about_us
from .view.show_to_widgets import ShowImage
from .view.manipulate_view import ManipulateView
from .view.control_frame import FrameWidgets
from .controller.serial_controller import AxisController
from .tools.utils import select_file, resize_image, calculate_height, read_image
from .controller.mouse_control_event import MouseController
from .parameter_source.camera_parameters import CameraParameters


[docs] class Controller(QtWidgets.QMainWindow): # create public variable. resized = QtCore.pyqtSignal() camera_parameter = 'camera_parameters/camera_parameters.json' def __init__(self, main_application): """ This Class is for control the widget event to the execute function. Args: main_application (): This argument send QWidget from main application. This also be a parent of this class, which is can access the function and variable from that class """ super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.parent = main_application self.image = None self.cap = None self.cam = False self.normal_view = True self.panorama_view = False self.anypoint_view = False self.axis_controller = False self.dir_save = None self.mapX = None self.mapY = None self.mapX_pano = None self.mapY_pano = None self.moildev = None self.type_camera = "Raspi" self.num = 0 self.pos_x = 0 self.w = 0 self.h = 0 self.result_image = None self.width_original_image = 300 self.width_result_image = 1400 self.angle = 0 self.connect_event() self.openCam = QtWidgets.QDialog() self.winOpenCam = OpenCameraSource(self, self.openCam) self.camParams = QtWidgets.QDialog() self.winCamParams = CameraParameters(self, self.camParams) self.show_image = ShowImage(self) self.video_controller = VideoController(self) self.anypoint = AnypointView(self) self.panorama = PanoramaView(self) self.axis_control = AxisController(self) self.control_mouse = MouseController(self) self.manipulate = ManipulateView(self) self.control_frame = FrameWidgets(self) self.video_controller.set_button_disable() self.ui.frame_panorama.hide() self.ui.frame_navigator.hide() self.ui.frame_axis.hide()
[docs] def connect_event(self): """ Connect every event on user interface like button event, mouse event and etc to the function processing. """ self.ui.actionLoad_Image.triggered.connect(self.open_image) self.ui.actionLoad_Video.triggered.connect(self.onclick_load_video) self.ui.actionOpen_Cam.triggered.connect( self.onclick_open_camera_button) self.ui.actionSave_Image.triggered.connect(self.save_image) self.ui.actionAbout_Apps.triggered.connect(about_us) self.ui.actionAbout_Us.triggered.connect(open_information_moildev) self.ui.actionCamera_Parameters.triggered.connect( self.open_cam_params_window) self.ui.actionExit.triggered.connect(self.onclick_exit) self.ui.btn_Open_Image.clicked.connect(self.open_image) self.ui.btn_Home.clicked.connect(self.go_to_home_application) self.ui.btn_Open_Cam.clicked.connect(self.onclick_open_camera_button) self.ui.btn_Open_Video.clicked.connect(self.onclick_load_video) self.ui.btn_Quit.clicked.connect(self.onclick_exit) self.ui.btn_show_help.clicked.connect(self.help) self.ui.btn_Save_Image.clicked.connect(self.save_image) self.ui.listWidget.currentItemChanged.connect( self.saved_image_activated) self.ui.pushButton_29.clicked.connect(about_us) self.ui.pushButton_18.clicked.connect(open_information_moildev) self.ui.btn_normal.clicked.connect(self.show_normal)
# self.resized.connect(self.set_place_frame_parameter)
[docs] def open_image(self): """ Open Dialog to search the file image from directory. This function also will read the comment from metadata image. """ self.reset_mode_view() if self.cam: self.video_controller.stop_video() self.cap.release() filename = select_file( "Select Image", "../", "Image Files (*.jpeg *.jpg *.png *.gif *.bmg)") if filename: img = exif_lib.MetaImage(filename) self.type_camera = img.read_comment() self.image = read_image(filename) self.h, self.w = self.image.shape[:2] self.video_controller.set_button_disable() self.show_to_window() self.cam = False img.close()
[docs] def connect_to_moildev(self): """ Connect to Moildev SDK, need provide camera parameter database and type of camera. """ if self.type_camera: self.moildev = Moildev(self.camera_parameter, self.type_camera) else: QtWidgets.QMessageBox.warning( self, "Warning!!", "The image not support for this application, \n\nPlease contact developer!!") print("the image not support for this application, please contact developer!!")
[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. """ self.reset_mode_view() video_source = select_file( "Select Video Files", "../", "Video Files (*.mp4 *.avi *.mpg *.gif *.mov)") if video_source: self.select_camera_type() if self.type_camera is not None: self.moildev = Moildev(self.camera_parameter, self.type_camera) self.running_video(video_source)
[docs] def select_camera_type(self): """ Select the camera type prompt. """ with open(self.camera_parameter) as f: data = json.load(f) new_list = [] for key in data.keys(): new_list.append(key) self.Dialog = QtWidgets.QDialog() self.Dialog.setObjectName("Dialog") self.Dialog.setWindowTitle("Select Camera !!!") self.Dialog.resize(240, 120) buttonBox = QtWidgets.QDialogButtonBox(self.Dialog) buttonBox.setGeometry(QtCore.QRect(20, 80, 200, 32)) buttonBox.setOrientation(QtCore.Qt.Horizontal) buttonBox.setStandardButtons( QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok) buttonBox.setObjectName("buttonBox") self.comboBox_cam_type = QtWidgets.QComboBox(self.Dialog) self.comboBox_cam_type.setGeometry(QtCore.QRect(20, 40, 200, 30)) self.comboBox_cam_type.setObjectName("comboBox") self.comboBox_cam_type.addItems(new_list) label = QtWidgets.QLabel(self.Dialog) label.setGeometry(QtCore.QRect(10, 10, 220, 30)) font = QtGui.QFont() font.setFamily("DejaVu Serif") font.setPointSize(13) label.setFont(font) label.setAlignment(QtCore.Qt.AlignCenter) label.setObjectName("label") label.setText("Select the camera type !!!") buttonBox.accepted.connect(self.dialog_camera_oke) buttonBox.rejected.connect(self.Dialog.reject) self.Dialog.exec_()
[docs] def dialog_camera_oke(self): """ The function will execute when you press accept or ok in dialog camera type selection. """ self.type_camera = self.comboBox_cam_type.currentText() self.Dialog.close()
[docs] def onclick_open_camera_button(self): """ Show the window of selection camera source. """ self.openCam.show()
[docs] def open_cam_params_window(self): """ Open the window of camera parameter form, this window you can update, add, and delete the camera parameter from database. """ self.camParams.show()
[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 = self.winOpenCam.camera_source_used() self.select_camera_type() if self.type_camera is not None: self.moildev = Moildev(self.camera_parameter, self.type_camera) self.running_video(camera_source)
[docs] def running_video(self, video_source): """ Open Video following the source given. Args: video_source (): the source of media, can be camera and video file. """ self.video_controller.set_button_enable() self.cap = cv2.VideoCapture(video_source) _, image = self.cap.read() if image is None: QtWidgets.QMessageBox.information( self, "Information", "No source camera founded") else: # print("here") self.cam = True self.video_controller.next_frame_slot()
[docs] def show_normal(self): """ Showing the original image into Label frame in UI. """ if self.image is not None: self.normal_view = True self.panorama_view = False self.anypoint_view = False self.angle = 0 self.show_image.show_original_image( self.image, self.width_original_image) self.show_image.show_result_image( self.image, self.width_result_image, self.angle) self.ui.frame_navigator.hide() self.ui.frame_panorama.hide()
# migrate to show result
[docs] def show_to_window(self): """ Showing the processing result image into the frame UI. """ if self.normal_view: self.show_image.show_original_image( self.image, self.width_original_image) self.show_image.show_result_image( self.image, self.width_result_image, self.angle) else: if self.panorama_view: # image = draw_polygon( # self.image.copy(), # self.mapX_pano, # self.mapY_pano) mapX = np.load( './plugins/Thread_inspection/process_image/maps_pano/mapX.npy') mapY = np.load( './plugins/Thread_inspection/process_image/maps_pano/mapY.npy') rho = self.panorama.rho self.result_image = cv2.remap( self.image, mapX, mapY, cv2.INTER_CUBIC) self.result_image = self.result_image[round( rho + round(self.moildev.getRhoFromAlpha(30))):self.h, 0:self.w] # print(self.width_result_image) self.show_image.show_original_image( self.image, self.width_original_image) else: image = draw_polygon(self.image.copy(), self.mapX, self.mapY) self.result_image = cv2.remap( self.image, self.mapX, self.mapY, cv2.INTER_CUBIC) self.show_image.show_original_image( image, self.width_original_image) self.show_image.show_result_image( self.result_image, self.width_result_image, self.angle)
[docs] def help(self): """ Showing the message box to show help information obout this application. """ self.openCam.close() help_moildev_apps()
[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: ss = datetime.datetime.now().strftime("%m%d%H_%M%S") if self.normal_view: image = self.image else: image = self.result_image if self.dir_save is None or self.dir_save == "": self.selectDir() else: name = self.dir_save + "/" + str(ss) + ".png" cv2.imwrite(name, image) img = exif_lib.MetaImage(name) img.modify_comment(self.type_camera) self.addWidget(image) img.close() QtWidgets.QMessageBox.information( self, "Information", "Image saved !!\n\nLoc @: " + self.dir_save)
[docs] def addWidget(self, image): """ Add the image widget in the list view of saved image. it can be reopen when you select. Args: image (): the image saved. """ height = calculate_height(self.image, 140) self.ui.listWidget.setIconSize(QtCore.QSize(140, height)) new_widget = QtWidgets.QListWidgetItem() image_ = resize_image(image, 140) imagePixmap = QtGui.QImage( image_.data, image_.shape[1], image_.shape[0], QtGui.QImage.Format_RGB888).rgbSwapped() icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(imagePixmap)) new_widget.setIcon(icon) new_widget.setText(str(datetime.datetime.now().strftime("%m%d%H_%M%S")) + ".png") self.ui.listWidget.addItem(new_widget)
[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.ui.listWidget.currentItem().text() img = exif_lib.MetaImage(filename) self.type_camera = img.read_comment() if self.cam: self.video_controller.pause_video() self.reset_mode_view() self.image = read_image(filename) self.h, self.w = self.image.shape[:2] img.close() self.show_to_window()
[docs] def selectDir(self): """ Select directory to save image. This function create to make it not always ask the directory by open dialog, after directory save not None, it will pass open dialog prompt. Returns: None. """ self.dir_save = QtWidgets.QFileDialog.getExistingDirectory( self, 'Select Save Folder') if self.dir_save: self.save_image()
[docs] def reset_mode_view(self): """ Update the properties view when you reset. """ self.moildev = None self.normal_view = True self.ui.btn_Record_video.setChecked(False)
[docs] def go_to_home_application(self): """ This function is for close the main window and show the home application to chose another application - self : represent the current user interface - self parent : represent the home window to select the application Returns: Back to home apps!! """ if self.cam: self.video_controller.stop_video() self.cap.release() self.parent.show() self.hide()
[docs] def onclick_exit(self): """ Function that connect to exit button to close tha window. """ self.close()
[docs] def resizeEvent(self, event): """ Resize window event controller. Args: event (): """ self.resized.emit()
[docs] def closeEvent(self, event): """ Control the close event by ask the question yes or no. Args: event (): Returns: """ reply = QtWidgets.QMessageBox.question( self, 'Message', "Are you sure to quit?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes: self.onclick_exit() event.accept() else: event.ignore()
[docs] class Internal_Inspection(Plugin): def __init__(self): """ The class that represent the plugins application, class name will be read as the name of application. """ super().__init__() self.apps = None self.description = "This is default application"
[docs] def perform_operation(self, argument): """ The main application will execute this function when click button open. Args: argument (): is the object widget from main application class. Returns: Will show the window of application. """ self.apps = Controller(argument) self.apps.show()