Beispiel #1
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
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