Beispiel #1
0
    def __init__(self):
        self.thread = threading.Thread(target=self.process_threading)
        self.thread_run = False

        self.input_queue = queue.Queue()
        self.output_queue = queue.Queue()

        self.output_images = OutputImagesStructure()

        self.complete_callback = None

        self.image_to_bw = BWImageToBytes()

        self.update_setting = False

        self.preview_image_width = 128
        self.preview_image_height = 64

        self.preview_image_width_temp = 128
        self.preview_image_height_temp = 64

        self.output_image_width = 128
        self.output_image_height = 64

        self.output_image_width_temp = 128
        self.output_image_height_temp = 64

        self.bw_threshold = 127
        self.bw_threshold_temp = 127
        self.bw_invert = False
        self.bw_invert_temp = False
    def __init__(self):
        self.thread = threading.Thread(target=self.process_threading)
        self.thread_run = False

        self.input_queue = queue.Queue()
        self.output_queue = queue.Queue()

        self.output_images = OutputImagesStructure()

        self.complete_callback = None

        self.image_to_bw = BWImageToBytes()

        self.update_setting = False

        self.preview_image_width = 128
        self.preview_image_height = 64

        self.preview_image_width_temp = 128
        self.preview_image_height_temp = 64

        self.output_image_width = 128
        self.output_image_height = 64

        self.output_image_width_temp = 128
        self.output_image_height_temp = 64

        self.bw_threshold = 127
        self.bw_threshold_temp = 127
        self.bw_invert = False
        self.bw_invert_temp = False

        self.dither_size = 0
        self.dither_size_temp = 0
        self.binarization_mode = 'threshold'
        self.binarization_mode_temp = 'threshold'

        self.binarization_equalizeHist = False
        self.binarization_equalizeHist_temp = False

        # init dll
        self.dithering = None
        self.error_diffusion = None
        self.load_dll()
Beispiel #3
0
    def __init__(self):
        # setup window
        self.window = QMainWindow()
        self.main_ui = Ui_mainWindow()
        self.main_ui.setupUi(self.window)
        self.main_ui.retranslateUi(self.window)

        self.imageModeWindow = ImageModeWindow(self.window, self.main_ui)
        self.videoModeWindow = VideoModeWindow(self.window, self.main_ui)
        self.screenModeWindow = ScreenModeWindow(self.window, self.main_ui)

        # BW image to bytes instance
        self.image_to_bw = BWImageToBytes()

        # image processing
        self.image_translator = ImageTranslate()
        self.image_translator.start()

        self.connectSignal()

        # show window
        self.window.show()
Beispiel #4
0
class ImageTranslate(object):
    def __init__(self):
        self.thread = threading.Thread(target=self.process_threading)
        self.thread_run = False

        self.input_queue = queue.Queue()
        self.output_queue = queue.Queue()

        self.output_images = OutputImagesStructure()

        self.complete_callback = None

        self.image_to_bw = BWImageToBytes()

        self.update_setting = False

        self.preview_image_width = 128
        self.preview_image_height = 64

        self.preview_image_width_temp = 128
        self.preview_image_height_temp = 64

        self.output_image_width = 128
        self.output_image_height = 64

        self.output_image_width_temp = 128
        self.output_image_height_temp = 64

        self.bw_threshold = 127
        self.bw_threshold_temp = 127
        self.bw_invert = False
        self.bw_invert_temp = False

        self.dither_size = 0
        self.dither_size_temp = 0
        self.dither_enabled = False
        self.dither_enabled_temp = False

    def start(self):
        if self.thread_run:
            return None
        self.thread_run = True
        self.thread.start()

    def stop(self):
        self.thread_run = False
        self.thread.join()

    def set_threshold(self, value):
        if value != 0:
            self.bw_threshold_temp = value

        self.update_setting = True

    def set_dither_size(self, size):
        self.dither_size_temp = size

        self.update_setting = True

    def set_dither_enable(self, enable):
        self.dither_enabled_temp = enable

        self.update_setting = True

    def set_invert(self, enable):
        if type(enable) == bool:
            self.bw_invert_temp = enable

        self.update_setting = True

    def set_preview_size(self, width, height):
        self.preview_image_width_temp = width
        self.preview_image_height_temp = height

        self.update_setting = True

    def set_output_size(self, width, height):
        self.output_image_width_temp = width
        self.output_image_height_temp = height

        self.update_setting = True

    def update_parameters(self):
        if not self.update_setting:
            return None
        self.update_setting = False

        self.bw_threshold = self.bw_threshold_temp
        self.bw_invert = self.bw_invert_temp

        self.dither_size = self.dither_size_temp
        self.dither_enabled = self.dither_enabled_temp

        self.preview_image_width = self.preview_image_width_temp
        self.preview_image_height = self.preview_image_height_temp

        self.output_image_width = self.output_image_width_temp
        self.output_image_height = self.output_image_height_temp

    def input_image(self, image):
        self.input_queue.put(image, timeout=0.1)

    def output_clean(self):
        while self.output_queue.qsize() > 0:
            self.output_queue.get()

    def read_images(self):
        try:
            return self.output_queue.get(timeout=0.1)
        except:
            return None

    def install_complete_callback(self, callback):
        if callback != None:
            self.complete_callback = callback

    def remove_complete_callback(self):
        self.complete_callback = None

    def image_translate(self, image):
        image_raw = cv.resize(
            image, (self.preview_image_width, self.preview_image_height))
        image_gray = cv.cvtColor(image_raw, cv.COLOR_BGR2GRAY)
        if not self.bw_invert:
            image_bw = (image_gray > self.bw_threshold) * np.uint8(255)
        else:
            image_bw = (image_gray <= self.bw_threshold) * np.uint8(255)
        image_out_bw2x = cv.resize(
            image_bw,
            (2 * self.output_image_width, 2 * self.output_image_height))

        if self.dither_enabled:
            image_gray_1x = cv.resize(
                image_gray,
                (self.output_image_width, self.output_image_height))
            image_gray_1x = cv.equalizeHist(image_gray_1x)
            image_out_bw = dither(image_gray_1x, self.dither_size)
        else:
            image_out_bw = cv.resize(
                image_bw, (self.output_image_width, self.output_image_height))

        image_out_bw_bytes = self.image_to_bw.convert(image_out_bw)

        self.output_images.raw = image_raw
        self.output_images.gray = image_gray
        self.output_images.bw = image_bw
        self.output_images.output_bw = image_out_bw
        self.output_images.output_bw2x = image_out_bw2x
        self.output_images.bytes = image_out_bw_bytes

    def output_images_to_queue(self):
        self.output_queue.put(self.output_images, timeout=0.1)

    def process_threading(self):
        while self.thread_run:
            try:
                image = self.input_queue.get(timeout=0.1)
                self.update_parameters()
                self.image_translate(image)
                self.output_images_to_queue()
                if self.complete_callback != None:
                    self.complete_callback(self.output_queue)
            except:
                pass
Beispiel #5
0
class MainWindow(object):
    def __init__(self):
        # setup window
        self.window = QMainWindow()
        self.main_ui = Ui_mainWindow()
        self.main_ui.setupUi(self.window)
        self.main_ui.retranslateUi(self.window)

        self.imageModeWindow = ImageModeWindow(self.window, self.main_ui)
        self.videoModeWindow = VideoModeWindow(self.window, self.main_ui)
        self.screenModeWindow = ScreenModeWindow(self.window, self.main_ui)

        # BW image to bytes instance
        self.image_to_bw = BWImageToBytes()

        # image processing
        self.image_translator = ImageTranslate()
        self.image_translator.start()

        self.connectSignal()

        # show window
        self.window.show()

    def connectSignal(self):
        # connect serial port widgets
        self.main_ui.pbt_scanSerialPort.clicked.connect(self.portScan)
        self.main_ui.combox_serialPortList.activated.connect(self.portSelect)
        self.main_ui.pbt_serialOpen.clicked.connect(self.portOpen)
        self.portOpened = False
        # connect display setting
        self.main_ui.spinBox_displayRow.valueChanged.connect(self.displayColumnRowSetting)
        self.main_ui.spinBox_displayCol.valueChanged.connect(self.displayColumnRowSetting)
        self.main_ui.checkBox_displayFlipH.clicked.connect(self.displayFlipModeSetting)
        self.main_ui.checkBox_displayFlipV.clicked.connect(self.displayFlipModeSetting)
        self.main_ui.comboBox_displayScanDirection.activated.connect(self.displayScanDirectionSetting)
        self.main_ui.comboBox_displayByteDirection.activated.connect(self.displayByteDirectionSetting)
        self.main_ui.comboBox_displaySignBit.activated.connect(self.displaySignBitSetting)
        self.displaySettingInit()
        # connect binarization setting
        self.main_ui.radioButton_binarizationThreshold.clicked.connect(self.binarizationSetting)
        self.main_ui.radioButton_binarizationDither.clicked.connect(self.binarizationSetting)
        self.main_ui.comboBox_ditherBayerSize.activated.connect(self.binarizationSetting)
        self.binarizationSetting()

    def portScan(self):
        portList = SerialPort.getDeviceList()
        self.main_ui.combox_serialPortList.clear()
        for portInfo, port in portList:
            self.main_ui.combox_serialPortList.addItem(portInfo, port)

    def portSelect(self):
        self.port = self.main_ui.combox_serialPortList.currentData()
        self.baudrate = self.main_ui.spinBox_baudrate.value()

    def portOpen(self):
        if self.portOpened == False:
            try:
                self.serial = SerialPort(self.port, self.baudrate)
                self.portOpened = True
                self.main_ui.pbt_serialOpen.setText('Close')
                self.imageModeWindow.addSendMethod(self.serial)
                self.videoModeWindow.addSendMethod(self.serial)
                self.screenModeWindow.addSendMethod(self.serial)
            except Exception:
                print('Serial port open false.')
        else:
            try:
                self.serial.close()
                self.serial = None
                self.portOpened = False
                self.main_ui.pbt_serialOpen.setText('Open')
                self.imageModeWindow.addSendMethod(None)
            except Exception:
                print('Serial port close false.')

    def binarizationSetting(self):
        if self.main_ui.radioButton_binarizationThreshold.isChecked():
            self.image_translator.set_dither_enable(False)
        else:
            self.image_translator.set_dither_enable(True)
            size_str = self.main_ui.comboBox_ditherBayerSize.currentText()
            size = int(size_str[:-1])
            self.image_translator.set_dither_size(size)

    def displaySettingInit(self):
        self.displayColumnRowSetting()
        self.displayFlipModeSetting()
        self.displayScanDirectionSetting()
        self.displayByteDirectionSetting()
        self.displaySignBitSetting()

    def displayColumnRowSetting(self):
        col = self.main_ui.spinBox_displayCol.value()
        row = self.main_ui.spinBox_displayRow.value()
        self.image_translator.set_output_size(col, row)

    def displayFlipModeSetting(self):
        flip_h = self.main_ui.checkBox_displayFlipH.isChecked()
        flip_v = self.main_ui.checkBox_displayFlipV.isChecked()
        self.image_to_bw.setHorizontalFlip(flip_h)
        self.image_to_bw.setVerticalFlip(flip_v)

    def displayScanDirectionSetting(self):
        scan_direction = self.main_ui.comboBox_displayScanDirection.currentText()
        if scan_direction == 'Horizontal':
            dir = 'H'
        else:
            dir = 'V'
        self.image_to_bw.setScanDirection(dir)

    def displayByteDirectionSetting(self):
        byte_direction = self.main_ui.comboBox_displayByteDirection.currentText()
        if byte_direction == 'Horizontal':
            dir = 'H'
        else:
            dir = 'V'
        self.image_to_bw.setByteDirection(dir)

    def displaySignBitSetting(self):
        sign_bit = self.main_ui.comboBox_displaySignBit.currentText()
        self.image_to_bw.setSignBit(sign_bit)

    def exit(self):
        if self.portOpened:
            self.serial.close()
        self.imageModeWindow.exit()
        self.videoModeWindow.exit()
        self.screenModeWindow.exit()
        self.image_translator.stop()
class ImageTranslate(object):

    def __init__(self):
        self.thread = threading.Thread(target=self.process_threading)
        self.thread_run = False

        self.input_queue = queue.Queue()
        self.output_queue = queue.Queue()

        self.output_images = OutputImagesStructure()

        self.complete_callback = None

        self.image_to_bw = BWImageToBytes()

        self.update_setting = False

        self.preview_image_width = 128
        self.preview_image_height = 64

        self.preview_image_width_temp = 128
        self.preview_image_height_temp = 64

        self.output_image_width = 128
        self.output_image_height = 64

        self.output_image_width_temp = 128
        self.output_image_height_temp = 64

        self.bw_threshold = 127
        self.bw_threshold_temp = 127
        self.bw_invert = False
        self.bw_invert_temp = False

        self.dither_size = 0
        self.dither_size_temp = 0
        self.binarization_mode = 'threshold'
        self.binarization_mode_temp = 'threshold'

        self.binarization_equalizeHist = False
        self.binarization_equalizeHist_temp = False

        # init dll
        self.dithering = None
        self.error_diffusion = None
        self.load_dll()


    def start(self):
        if self.thread_run:
            return None
        self.thread_run = True
        self.thread.start()

    def stop(self):
        self.thread_run = False
        self.thread.join()

    def load_dll(self):
        dll_lib = CDLL("./image_processing/image_processing.dll")
        self.dithering = dll_lib.dithering
        self.error_diffusion = dll_lib.error_diffusion

        # set args type
        self.dithering.argtypes = [np.ctypeslib.ndpointer(c_uint8),
                                   c_int,
                                   c_int,
                                   c_int]
        self.dithering.restype = c_int

        self.error_diffusion.argtypes = [np.ctypeslib.ndpointer(c_uint8),
                                         c_int,
                                         c_int]
        self.error_diffusion.restype = c_int

    def set_threshold(self, value):
        if value != 0:
            self.bw_threshold_temp = value

        self.update_setting = True

    def set_dither_size(self, size):
        self.dither_size_temp = size

        self.update_setting = True

    def set_binarization_mode(self, mode):
        self.binarization_mode_temp = mode

        self.update_setting = True

    def set_invert(self, enable):
        if type(enable) == bool:
            self.bw_invert_temp = enable

        self.update_setting = True

    def set_equalizrHist(self, enable):
        if type(enable) == bool:
            self.binarization_equalizeHist_temp = enable

        self.update_setting = True

    def set_preview_size(self, width, height):
        self.preview_image_width_temp = width
        self.preview_image_height_temp = height

        self.update_setting = True

    def set_output_size(self, width, height):
        self.output_image_width_temp = width
        self.output_image_height_temp = height

        self.update_setting = True

    def update_parameters(self):
        if not self.update_setting:
            return None
        self.update_setting = False

        self.bw_threshold = self.bw_threshold_temp
        self.bw_invert = self.bw_invert_temp

        self.dither_size = self.dither_size_temp
        self.binarization_mode = self.binarization_mode_temp
        self.binarization_equalizeHist = self.binarization_equalizeHist_temp

        self.preview_image_width = self.preview_image_width_temp
        self.preview_image_height = self.preview_image_height_temp

        self.output_image_width = self.output_image_width_temp
        self.output_image_height = self.output_image_height_temp

    def input_image(self, image):
        self.input_queue.put(image, timeout=0.1)

    def output_clean(self):
        while self.output_queue.qsize() > 0:
            self.output_queue.get()

    def read_images(self):
        try:
            return self.output_queue.get(timeout=0.1)
        except:
            return None

    def install_complete_callback(self, callback):
        if callback != None:
            self.complete_callback = callback

    def remove_complete_callback(self):
        self.complete_callback = None

    def image_translate(self, image):
        # s1 = time.perf_counter()
        w = self.preview_image_width
        h = self.preview_image_height

        image_raw = cv.resize(image, (w, h))
        image_gray = cv.cvtColor(image_raw, cv.COLOR_BGR2GRAY)

        if self.binarization_equalizeHist:
            image_gray = cv.equalizeHist(image_gray)

        image_out_gray_2x = cv.resize(image_gray, (2 * self.output_image_width, 2 * self.output_image_height))
        image_out_gray_1x = cv.resize(image_gray, (self.output_image_width, self.output_image_height))

        if self.binarization_mode == 'threshold':
            if not self.bw_invert:
                ret, image_bw = cv.threshold(image_gray, self.bw_threshold, 255, cv.THRESH_BINARY)
                ret, image_out_bw2x = cv.threshold(image_out_gray_2x, self.bw_threshold, 255, cv.THRESH_BINARY)
                ret, image_out_bw = cv.threshold(image_out_gray_1x, self.bw_threshold, 255, cv.THRESH_BINARY)
            else:
                ret, image_bw = cv.threshold(image_gray, self.bw_threshold, 255, cv.THRESH_BINARY_INV)
                ret, image_out_bw2x = cv.threshold(image_out_gray_2x, self.bw_threshold, 255, cv.THRESH_BINARY_INV)
                ret, image_out_bw = cv.threshold(image_out_gray_1x, self.bw_threshold, 255, cv.THRESH_BINARY_INV)
        elif self.binarization_mode == 'dithering':
            image_bw = image_gray.copy()
            self.dithering(image_bw, w, h, self.dither_size)

            image_out_bw2x = image_out_gray_2x
            self.dithering(image_out_bw2x, 2 * self.output_image_width, 2 * self.output_image_height, self.dither_size)

            image_out_bw = image_out_gray_1x
            self.dithering(image_out_bw, self.output_image_width, self.output_image_height, self.dither_size)
        elif self.binarization_mode == 'error_diff':
            image_bw = image_gray.copy()
            self.error_diffusion(image_bw, w, h)

            image_out_bw2x = image_out_gray_2x
            self.error_diffusion(image_out_bw2x, 2 * self.output_image_width, 2 * self.output_image_height)

            image_out_bw = image_out_gray_1x
            self.error_diffusion(image_out_bw, self.output_image_width, self.output_image_height)
        else:
            return None
        # s1 = time.perf_counter()
        image_out_bw_bytes = self.image_to_bw.convert(image_out_bw)
        # s2 = time.perf_counter()
        # dt = s2-s1
        # print('dt: %.6f, fps: %.3f' % (dt, 1/dt))

        self.output_images.raw = image_raw
        self.output_images.gray = image_gray
        self.output_images.bw = image_bw
        self.output_images.output_bw = image_out_bw
        self.output_images.output_bw2x = image_out_bw2x
        self.output_images.bytes = image_out_bw_bytes

    def output_images_to_queue(self):
        self.output_queue.put(self.output_images, timeout=0.1)

    def process_threading(self):
        while self.thread_run:
            try:
                image = self.input_queue.get(timeout=0.1)
                self.update_parameters()
                self.image_translate(image)
                self.output_images_to_queue()
                if self.complete_callback != None:
                    self.complete_callback(self.output_queue)
            except:
                pass