class Worker(QThread): result = pyqtSignal(np.ndarray) leftImage = pyqtSignal(np.ndarray) rightImage = pyqtSignal(np.ndarray) def __init__(self, parent=None): super().__init__(parent) self._mutex = QMutex() self._condition = QWaitCondition() self.frame = None self.parameters = None self.abort = False def processFrame(self, frame, parameters): self._mutex.lock() self.frame = frame self.parameters = parameters self._mutex.unlock() if not self.isRunning(): self.start() else: self._condition.wakeOne() def run(self): while not self.abort: # copy new frame and parameters: self._mutex.lock() frame = self.frame parameters = self.parameters self.frame = None self.parameters = None self._mutex.unlock() # convert frame to grayscale and rotate to give the correction orientation data = frame.sum(axis=2).astype(np.float64) data = np.rot90(data, axes=(1, 0)) # split data in half and subtract the two halves: center = data.shape[0] // 2 left = data[0:center, :] right = data[center:, :] res = left - right # update the user interface: self.result.emit(res) self.leftImage.emit(left) self.rightImage.emit(right) # see if new data is available, go to sleep if not self._mutex.lock() data_available = self.frame is not None and self.parameters is not None if not data_available: self._condition.wait(self._mutex) self._mutex.unlock()
class Worker(QThread): result = pyqtSignal(np.ndarray) def __init__(self, parent=None): super().__init__(parent) self._mutex = QMutex() self._condition = QWaitCondition() self.frame = None self.parameters = None self.abort = False def processFrame(self, frame, parameters): self._mutex.lock() self.frame = frame self.parameters = parameters self._mutex.unlock() if not self.isRunning(): self.start() else: self._condition.wakeOne() def run(self): while not self.abort: # copy new frame and parameters: self._mutex.lock() frame = self.frame parameters = self.parameters self.frame = None self.parameters = None self._mutex.unlock() homogenize = parameters["homogenize"] sigma = parameters["sigma"] blur = parameters["blur"] if homogenize: frame = vtc.highpass(frame, sigma, blur) #frame = np.uint16(np.float32(frame) / np.float32(frame.max()) * 255) # update the user interface: self.result.emit(frame) # see if new data is available, go to sleep if not self._mutex.lock() data_available = self.frame is not None and self.parameters is not None if not data_available: self._condition.wait(self._mutex) self._mutex.unlock()
class FetchPage(QThread): fetchSignal = pyqtSignal(str, name='fetchComplete') def __init__(self, parent=None): super(FetchPage, self).__init__(parent) print('thread initialized') self.mutex = QMutex() self.condition = QWaitCondition() self.restart = False self.abort = False def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait() def fetch(self, page): locker = QMutexLocker(self.mutex) self.page = page if page.content is not None: print('Returning old content') self.fetchSignal.emit(page.content) else: if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def run(self): print("running page fetch for " + self.page.title) rest_api = RestAPI() self.page.content = (rest_api.get_page_content(self.page.content_url)) # print(self.page.content) self.fetchSignal.emit(self.page.content) # self.fetchSignal.emit() print('signal emitted') self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock()
class STT(QThread): signal_stt_done = pyqtSignal(list) def __init__(self, max_alternatives=1): super().__init__() self.max_alter = max_alternatives self._mutex = QMutex() self._abort = False self._condition = QWaitCondition() self.client = speech.Client() self.file_path = None def __del__(self): self._abort = True self.wait() def activate(self, audio_file_path): self.file_path = audio_file_path self._condition.wakeOne() def run(self): while True: if self._abort: return self._mutex.lock() self._condition.wait(self._mutex) ### DOING THING trans = [] with open(self.file_path, 'rb') as audio_file: sample = self.client.sample(content=audio_file.read(), sample_rate=16000, encoding=speech.Encoding.FLAC) try: alternatives = sample.sync_recognize( language_code='en-US', max_alternatives=self.max_alter) for a in alternatives: trans.append(a.transcript) except ValueError as e: print("error: ", e) self.signal_stt_done.emit(trans) ### DONE DOING THING self._mutex.unlock()
class SyncAllThread(QThread): syncCompleteSignal = pyqtSignal(Dbm, name="syncComplete") def __init__(self, parent=None): super(SyncAllThread, self).__init__(parent) print("thread initialized") self.mutex = QMutex() self.condition = QWaitCondition() self.restart = False self.abort = False def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait() def sync(self): locker = QMutexLocker(self.mutex) self.dbm = Dbm() print("in sync thread") if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def run(self): print("running sync thread") self.dbm.fetch() # print(self.page.content) self.syncCompleteSignal.emit(self.dbm) # self.fetchSignal.emit() print("signal emitted") self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock()
class RequestHandler(QObject): """ Worker object for handling requests. """ waitingRequest = pyqtSignal() requestAccepted = pyqtSignal() error = pyqtSignal(Exception) terminated = pyqtSignal() def __init__(self, parent): super(RequestHandler, self).__init__() self.parent = parent self.__terminated = False self.mutex = QMutex() self.waitForClick = QWaitCondition() def run(self): """ Uses parent's server to listen for request. When a valid request is handled, emits requestAccepted singal and waits on Mutex condition. The parent should wake the worker when a click is made via wakeOnClick() method. When woken respond to the request with the click that was made. Can be terminated from the parent. Listening ignores bad requests. If OSError occurres, terminates itself and emits error signal. On termination emits the terminate signal. """ # print('run') self.__terminated = False while not self.__terminated: # print('Waiting for request') self.waitingRequest.emit() try: self.parent.server.listen(self.onMoveRequest) except OSError as e: print('error ', e) self.error.emit(e) self.__terminated = True except BadRequestError as e: print(e) continue print('Worker terminated') self.terminated.emit() def onMoveRequest(self, name, macroboard): if self.__terminated: return None self.opponentName = name self.macroboard = macroboard self.requestAccepted.emit() self.__sleepUntilClick() if self.__terminated: return None move = self.parent.last_click return move def __sleepUntilClick(self): self.mutex.lock() self.waitForClick.wait(self.mutex) self.mutex.unlock() def wakeOnClick(self): self.mutex.lock() self.waitForClick.wakeOne() self.mutex.unlock() def terminate(self): """ Terminates the worker. """ if self.__terminated: return self.__terminated = True self.wakeOnClick() self.parent.server.stop()
class RenderThread(QThread): ColormapSize = 512 renderedImage = pyqtSignal(QImage, float) def __init__(self, parent=None): super(RenderThread, self).__init__(parent) self.mutex = QMutex() self.condition = QWaitCondition() self.centerX = 0.0 self.centerY = 0.0 self.scaleFactor = 0.0 self.resultSize = QSize() self.colormap = [] self.restart = False self.abort = False for i in range(RenderThread.ColormapSize): self.colormap.append( self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize))) def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait() def render(self, centerX, centerY, scaleFactor, resultSize): locker = QMutexLocker(self.mutex) self.centerX = centerX self.centerY = centerY self.scaleFactor = scaleFactor self.resultSize = resultSize if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def run(self): while True: self.mutex.lock() resultSize = self.resultSize scaleFactor = self.scaleFactor centerX = self.centerX centerY = self.centerY self.mutex.unlock() halfWidth = resultSize.width() // 2 halfHeight = resultSize.height() // 2 image = QImage(resultSize, QImage.Format_RGB32) NumPasses = 8 curpass = 0 while curpass < NumPasses: MaxIterations = (1 << (2 * curpass + 6)) + 32 Limit = 4 allBlack = True for y in range(-halfHeight, halfHeight): if self.restart: break if self.abort: return ay = 1j * (centerY + (y * scaleFactor)) for x in range(-halfWidth, halfWidth): c0 = centerX + (x * scaleFactor) + ay c = c0 numIterations = 0 while numIterations < MaxIterations: numIterations += 1 c = c * c + c0 if abs(c) >= Limit: break numIterations += 1 c = c * c + c0 if abs(c) >= Limit: break numIterations += 1 c = c * c + c0 if abs(c) >= Limit: break numIterations += 1 c = c * c + c0 if abs(c) >= Limit: break if numIterations < MaxIterations: image.setPixel( x + halfWidth, y + halfHeight, self.colormap[numIterations % RenderThread.ColormapSize]) allBlack = False else: image.setPixel(x + halfWidth, y + halfHeight, qRgb(0, 0, 0)) if allBlack and curpass == 0: curpass = 4 else: if not self.restart: self.renderedImage.emit(image, scaleFactor) curpass += 1 self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock() def rgbFromWaveLength(self, wave): r = 0.0 g = 0.0 b = 0.0 if wave >= 380.0 and wave <= 440.0: r = -1.0 * (wave - 440.0) / (440.0 - 380.0) b = 1.0 elif wave >= 440.0 and wave <= 490.0: g = (wave - 440.0) / (490.0 - 440.0) b = 1.0 elif wave >= 490.0 and wave <= 510.0: g = 1.0 b = -1.0 * (wave - 510.0) / (510.0 - 490.0) elif wave >= 510.0 and wave <= 580.0: r = (wave - 510.0) / (580.0 - 510.0) g = 1.0 elif wave >= 580.0 and wave <= 645.0: r = 1.0 g = -1.0 * (wave - 645.0) / (645.0 - 580.0) elif wave >= 645.0 and wave <= 780.0: r = 1.0 s = 1.0 if wave > 700.0: s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0) elif wave < 420.0: s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0) r = pow(r * s, 0.8) g = pow(g * s, 0.8) b = pow(b * s, 0.8) return qRgb(r * 255, g * 255, b * 255)
class RenderThread(QThread): ColormapSize = 512 renderedImage = pyqtSignal(QImage, float) def __init__(self, parent=None): super(RenderThread, self).__init__(parent) self.mutex = QMutex() self.condition = QWaitCondition() self.centerX = 0.0 self.centerY = 0.0 self.scaleFactor = 0.0 self.resultSize = QSize() self.colormap = [] self.restart = False self.abort = False for i in range(RenderThread.ColormapSize): self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize))) def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait() def render(self, centerX, centerY, scaleFactor, resultSize): locker = QMutexLocker(self.mutex) self.centerX = centerX self.centerY = centerY self.scaleFactor = scaleFactor self.resultSize = resultSize if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def run(self): while True: self.mutex.lock() resultSize = self.resultSize scaleFactor = self.scaleFactor centerX = self.centerX centerY = self.centerY self.mutex.unlock() halfWidth = resultSize.width() // 2 halfHeight = resultSize.height() // 2 image = QImage(resultSize, QImage.Format_RGB32) NumPasses = 8 curpass = 0 while curpass < NumPasses: MaxIterations = (1 << (2 * curpass + 6)) + 32 Limit = 4 allBlack = True for y in range(-halfHeight, halfHeight): if self.restart: break if self.abort: return ay = 1j * (centerY + (y * scaleFactor)) for x in range(-halfWidth, halfWidth): c0 = centerX + (x * scaleFactor) + ay c = c0 numIterations = 0 while numIterations < MaxIterations: numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break if numIterations < MaxIterations: image.setPixel(x + halfWidth, y + halfHeight, self.colormap[numIterations % RenderThread.ColormapSize]) allBlack = False else: image.setPixel(x + halfWidth, y + halfHeight, qRgb(0, 0, 0)) if allBlack and curpass == 0: curpass = 4 else: if not self.restart: self.renderedImage.emit(image, scaleFactor) curpass += 1 self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock() def rgbFromWaveLength(self, wave): r = 0.0 g = 0.0 b = 0.0 if wave >= 380.0 and wave <= 440.0: r = -1.0 * (wave - 440.0) / (440.0 - 380.0) b = 1.0 elif wave >= 440.0 and wave <= 490.0: g = (wave - 440.0) / (490.0 - 440.0) b = 1.0 elif wave >= 490.0 and wave <= 510.0: g = 1.0 b = -1.0 * (wave - 510.0) / (510.0 - 490.0) elif wave >= 510.0 and wave <= 580.0: r = (wave - 510.0) / (580.0 - 510.0) g = 1.0 elif wave >= 580.0 and wave <= 645.0: r = 1.0 g = -1.0 * (wave - 645.0) / (645.0 - 580.0) elif wave >= 645.0 and wave <= 780.0: r = 1.0 s = 1.0 if wave > 700.0: s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0) elif wave < 420.0: s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0) r = pow(r * s, 0.8) g = pow(g * s, 0.8) b = pow(b * s, 0.8) return qRgb(r*255, g*255, b*255)
class BackgroundThread(QThread): def __init__(self, parent=None): super(BackgroundThread, self).__init__(parent) self._mutex = QMutex() self._condition = QWaitCondition() self._activating = False self._input = None # when program is closed self._abort = False def __del__(self): self._mutex.lock() self._abort = True self._condition.wakeOne() self._mutex.unlock() # wait for gracefully stop self.wait() def _taskStart(self, taskInput): ''' this function should not be called from outside :return: ''' # this must re-implemented in derived class pass def _taskEnd(self, taskOutput): ''' this function should not be called from outside :return: ''' # this must re-implemented in derived class pass def activate(self, input=None): locker = QMutexLocker(self._mutex) if not self._activating: self._activating = True self._input = input # if not running than we start the thread, otherwise we wake it up if not self.isRunning(): self.start() else: self._condition.wakeOne() def run(self): while True: if self._abort: return self._mutex.lock() activating = self._activating input = self._input self._mutex.unlock() if activating: # start long running task taskOutput = self._taskStart(input) # task comleted => report result self._taskEnd(taskOutput) # switch off self._activating self._mutex.lock() self._activating = False self._mutex.unlock() else: self._mutex.lock() self._condition.wait(self._mutex) self._mutex.unlock()
class ConversionThread(QThread): ndarray_available = pyqtSignal(np.ndarray) def __init__(self): super().__init__() self._mutex = QMutex() self._abort = False self._condition = QWaitCondition() self.frame = None def process_frame(self, frame: QVideoFrame): with QMutexLocker(self._mutex): self.frame = frame if not self.isRunning(): self.start() else: self._condition.wakeOne() def stop(self): with QMutexLocker(self._mutex): self._abort = True self._condition.wakeOne() def run(self): self._abort = False while True: with QMutexLocker(self._mutex): if self._abort: break frame = self.frame self.frame = None pixel_format = frame.pixelFormat() image_format = QVideoFrame.imageFormatFromPixelFormat(pixel_format) if image_format == QImage.Format_Invalid: qDebug("WARNING: Could not convert video frame to image!") return if not frame.map(QAbstractVideoBuffer.ReadOnly): qDebug("WARNING: Could not map video frame!") return width = frame.width() height = frame.height() bytes_per_line = frame.bytesPerLine() image = QImage(frame.bits(), width, height, bytes_per_line, image_format) image = image.convertToFormat(QImage.Format_RGB32) frame.unmap() # fix upside-down data for windows if platform.system() == "Windows": image = image.mirrored(vertical=True) # now convert QImage to ndarray pointer = image.constBits() pointer.setsize(image.byteCount()) array = np.array(pointer).reshape(image.height(), image.width(), 4) # get rid of the transparency channel and organize the colors as rgb # NB: it would be safer to figure out the image format first, and where the transparency channel is # stored... array = array[:, :, 0:3:][:, :, ::-1] self.ndarray_available.emit(array) # see if new data is available, go to sleep if not with QMutexLocker(self._mutex): if self.frame is None: self._condition.wait(self._mutex)
class RabbitMQPublishThread(QThread): ROUTING_KEY = 'ports.to_check' DURABLE = False QOS = 1 def __init__(self, amqp_url, parent=None): super(RabbitMQPublishThread, self).__init__() self.ioloop = pyuv.Loop.default_loop() self.rabbitmq = {} self._connection = None self._channel = None self._closing = False self._consumer_tag = None self._url = amqp_url self.mutex = QMutex() self.condition = QWaitCondition() self.restart = False self.abort = False def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() def run(self): while True: self.mutex.lock() self.mutex.unlock() self._connection = self.connect() self._connection.ioloop.run() self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock() def connect(self): def on_connection_closed(connection, reply_code, reply_text): self._channel = None if self._closing: self._connection.ioloop.stop() else: warn('Connection closed, reopening in 5 seconds: (%s) %s', reply_code, reply_text) self._connection.add_timeout(5, self.reconnect) def on_connection_open(unused_connection): info('Connection opened') self._connection.add_on_close_callback(on_connection_closed) self._connection.channel(on_open_callback=self.on_channel_open) info('Connecting to %s', self._url) return LibuvConnection(pika.URLParameters(self._url), on_connection_open, stop_ioloop_on_close=False) def reconnect(self): self._connection.ioloop.stop() if not self._closing: self._connection = self.connect() self._connection.ioloop.run() def on_channel_open(self, channel): def on_bindok(unused_frame): info('Queue bound') def on_queue_declareok(method_frame): self._channel.queue_bind(on_bindok, 'proxies.port.proxycheck', 'proxies', 'proxies.port.proxycheck') def on_exchange_declareok(unused_frame): self._channel.queue_declare(on_queue_declareok, 'proxies.port.proxycheck') def setup_exchange(exchange_name): info('Declaring exchange %s', exchange_name) self._channel.exchange_declare(on_exchange_declareok, exchange_name, 'direct') info('Channel opened') self._channel = channel self._channel.basic_qos(prefetch_count=self.QOS) self.add_on_channel_close_callback() setup_exchange('proxies') def add_on_channel_close_callback(self): info('Adding channel close callback') self._channel.add_on_close_callback(self.on_channel_closed) def on_channel_closed(self, channel, reply_code, reply_text): warn('Channel %i was closed: (%s) %s', channel, reply_code, reply_text) self._connection.close() # self.start_consuming() def start_consuming(self): info('Issuing consumer related RPC commands') self.add_on_cancel_callback() self._consumer_tag = self._channel.basic_consume( self.on_message, self.QUEUE) def add_on_cancel_callback(self): info('Adding consumer cancellation callback') self._channel.add_on_cancel_callback(self.on_consumer_cancelled) def on_consumer_cancelled(self, method_frame): info('Consumer was cancelled remotely, shutting down: %r', method_frame) if self._channel: self._channel.close() def on_message(self, unused_channel, basic_deliver, properties, body): info('Received message # %s from %s: %s', basic_deliver.delivery_tag, properties.app_id, body) def acknowledge_message(self, delivery_tag): info('Acknowledging message %s', delivery_tag) self._channel.basic_ack(delivery_tag) def stop_consuming(self): if self._channel: info('Sending a Basic.Cancel RPC command to RabbitMQ') self._channel.basic_cancel(self.on_cancelok, self._consumer_tag) def on_cancelok(self, unused_frame): info('RabbitMQ acknowledged the cancellation of the consumer') self.close_channel() def close_channel(self): info('Closing the channel') self._channel.close() def stop(self): info('Stopping') self._closing = True self.stop_consuming() self._connection.ioloop.start() info('Stopped') def close_connection(self): """This method closes the connection to RabbitMQ.""" info('Closing connection') self._connection.close()
class VoiceRec(QThread): signal_recording_done = pyqtSignal(str) def __init__(self, recording_time=5): super().__init__() self._rec_time = recording_time # self._is_active = False self._mutex = QMutex() self._abort = False self._condition = QWaitCondition() def __del__(self): self._abort = True self.wait() def activate(self): # self._mutex.lock() # self._is_active = True # self._mutex.unlock() # self._is_active = True self._condition.wakeOne() # def deactivate(self): # self._mutex.lock() # self._is_active = False # self._mutex.unlock() def run(self): while True: if self._abort: return # activating = self._is_active # if activating: # with tempfile.NamedTemporaryFile(suffix=".flac", delete=False) as f: # flacFilename = f.name # cmd = 'rec --channels=1 --bits=16 --rate=16000 {} trim 0 {:d}'.format(flacFilename, self._rec_time) # print("recording...") # p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) # # wait for subprocess to finished # p.communicate() # print("finished recording") # # self._mutex.lock() # self._is_active = False # self._mutex.unlock() # # self.signal_recording_done.emit(flacFilename) # else: # self._mutex.lock() # self._condition.wait(self._mutex) # self._mutex.unlock() self._mutex.lock() self._condition.wait(self._mutex) # DOING STUFF with tempfile.NamedTemporaryFile(suffix=".flac", delete=False) as f: flacFilename = f.name cmd = 'rec --channels=1 --bits=16 --rate=16000 {} trim 0 {:d}'.format( flacFilename, self._rec_time) print("recording...") p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) # wait for subprocess to finished p.communicate() print("finished recording") self.signal_recording_done.emit(flacFilename) self._mutex.unlock()
class FortuneThread(QThread): newFortune = pyqtSignal(str) error = pyqtSignal(int, str) def __init__(self, parent=None): super(FortuneThread, self).__init__(parent) self.quit = False self.hostName = '' self.cond = QWaitCondition() self.mutex = QMutex() self.port = 0 def __del__(self): self.mutex.lock() self.quit = True self.cond.wakeOne() self.mutex.unlock() self.wait() def requestNewFortune(self, hostname, port): locker = QMutexLocker(self.mutex) self.hostName = hostname self.port = port if not self.isRunning(): self.start() else: self.cond.wakeOne() def run(self): self.mutex.lock() serverName = self.hostName serverPort = self.port self.mutex.unlock() while not self.quit: Timeout = 5 * 1000 socket = QTcpSocket() socket.connectToHost(serverName, serverPort) if not socket.waitForConnected(Timeout): self.error.emit(socket.error(), socket.errorString()) return while socket.bytesAvailable() < 2: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return instr = QDataStream(socket) instr.setVersion(QDataStream.Qt_4_0) blockSize = instr.readUInt16() while socket.bytesAvailable() < blockSize: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return self.mutex.lock() fortune = instr.readQString() self.newFortune.emit(fortune) self.cond.wait(self.mutex) serverName = self.hostName serverPort = self.port self.mutex.unlock()
class RenderThread(QThread): renderedImage = pyqtSignal(QImage) def __init__(self, parent=None): super(RenderThread, self).__init__(parent) self.mutex = QMutex() self.state = make_default_state() self.condition = QWaitCondition() self.restart = False self.abort = False self.base_image = None self.canvas = self.make_canvas(800, 600) def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait() def make_canvas(self, width, height): im_np = np.ones((width, height, 3), dtype=np.uint8) im_np = np.transpose(im_np, (1, 0, 2)).copy() canvas = QImage(im_np, im_np.shape[1], im_np.shape[0], QImage.Format_RGB888) return canvas def load_image(self, path): image = QImage(path) self.mutex.lock() self.base_image = image self.canvas = self.make_canvas(self.base_image.width(), self.base_image.height()) self.mutex.unlock() def render(self, state=None): locker = QMutexLocker(self.mutex) # update renderable state if state: # print("Update render state") # print("state =>", state) self.state = state if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def run(self): while True: self.mutex.lock() state = self.state # if self.base_image: # image = self.base_image # else: # # base = QImage("/Users/jonathan/Documents/Scan 1.jpeg") # # base = base.scaled(image.size(), Qt.KeepAspectRatio) self.mutex.unlock() painter = QPainter() painter.begin(self.canvas) brush = QBrush(QColor("#FF00FF")) painter.setBrush(brush) painter.setPen(Qt.white) # painter.fillRect(image.rect(), Qt.black) # painter.drawImage(image.rect(), image) if state.dragging: painter.setOpacity(0.2) painter.drawRect(state.drag_start_pos[0], state.drag_start_pos[1], state.mouse_pos[0] - state.drag_start_pos[0], state.mouse_pos[1] - state.drag_start_pos[1]) for box in state.bounding_boxes: box.draw(painter) painter.end() if not self.restart: self.renderedImage.emit(self.canvas) self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock()
class RFID(QThread): tagScan = pyqtSignal(int, str, int, str, name='tagScan', arguments=['tag', 'hash', 'time', 'debugText']) tagScanError = pyqtSignal(int, int, str, name='tagScanError', arguments=['error', 'time', 'debugText']) @pyqtProperty(int) def errPacket(self): return -1 @pyqtProperty(int) def errChecksum(self): return -2 def __init__(self, portName='', loglevel='WARNING'): QThread.__init__(self) self.logger = Logger(name='ratt.rfid') self.logger.setLogLevelStr(loglevel) self.debug = self.logger.isDebug() self.cond = QWaitCondition() self.mutex = QMutex() self.portName = portName self.waitTimeout = 250 self.quit = False def monitor(self): if not self.isRunning(): self.start() else: self.cond.wakeOne() def dump_pkt(self, bytes): bstr = '' for b in bytes: byte = ord(b) bstr += '%02x ' % byte return bstr def decode_gwiot(self, bytes): # # sample packet from "Gwiot 7941e V3.0" eBay RFID module: # # 00 01 02 03 04 05 06 07 08 09 BYTE # # ----------------------------------------------------------- # 02 0A 02 11 00 0D EF 80 7B 03 # | | | | | | | | | | # STX ?? ?? ?? id3 id2 id1 id0 sum ETX # # checksum (byte 8, 'sum') is a simple 8-bit XOR of bytes 01 through 07 # starting the checksum with the value of 'sum' or starting with 0 and # including the value of 'sum' in the calculation will net a checksum # value of 0 when correct # # the actual tag value is contained in bytes 04 through 07 as a 32-bit # unsigned integer. byte 04 ('id3') is the most significant byte, while # byte 07 ('id0') is the least significant byte. # if bytes.length() == 10 and ord(bytes[0]) == 0x02 and ord( bytes[9]) == 0x03: checksum = ord(bytes[8]) for i in range(1, 8): checksum = checksum ^ ord(bytes[i]) self.logger.debug( 'calc checksum byte %d (%2x), checksum = %2x' % (i, ord(bytes[i]), checksum)) if checksum == 0: tag = (ord(bytes[4]) << 24) | (ord(bytes[5]) << 16) | ( ord(bytes[6]) << 8) | ord(bytes[7]) self.logger.debug("serial read: " + self.dump_pkt(bytes)) self.logger.debug('tag = %10.10d' % tag) return tag else: self.logger.warning("checksum error") return self.errChecksum else: self.logger.warning("packet error") return self.errPacket def hash_tag(self, tag): m = hashlib.sha224() tag_str = '%.10d' % int(tag) m.update(str(tag_str).encode()) tag_hash = m.hexdigest() self.logger.debug('hash: %s' % tag_hash) return tag_hash def run(self): serial = QSerialPort() serial.setPortName(self.portName) if not serial.open(QIODevice.ReadOnly): self.logger.error("can't open serial port") return while not self.quit: if serial.waitForReadyRead(self.waitTimeout): bytes = serial.readAll() while serial.waitForReadyRead(10): bytes += serial.readAll() tag = self.decode_gwiot(bytes) now = calendar.timegm(time.gmtime()) self.logger.debug("tag=%d, now=%d" % (tag, now)) if tag > 0: self.tagScan.emit(tag, self.hash_tag(tag), now, self.dump_pkt(bytes)) else: self.tagScanError.emit(tag, now, self.dump_pkt(bytes))
class FortuneThread(QThread): newFortune = pyqtSignal(str) error = pyqtSignal(int, str) def __init__(self, parent=None): super(FortuneThread, self).__init__(parent) self.quit = False self.hostName = "" self.cond = QWaitCondition() self.mutex = QMutex() self.port = 0 def __del__(self): self.mutex.lock() self.quit = True self.cond.wakeOne() self.mutex.unlock() self.wait() def requestNewFortune(self, hostname, port): locker = QMutexLocker(self.mutex) self.hostName = hostname self.port = port if not self.isRunning(): self.start() else: self.cond.wakeOne() def run(self): self.mutex.lock() serverName = self.hostName serverPort = self.port self.mutex.unlock() while not self.quit: Timeout = 5 * 1000 socket = QTcpSocket() socket.connectToHost(serverName, serverPort) if not socket.waitForConnected(Timeout): self.error.emit(socket.error(), socket.errorString()) return while socket.bytesAvailable() < 2: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return instr = QDataStream(socket) instr.setVersion(QDataStream.Qt_4_0) blockSize = instr.readUInt16() while socket.bytesAvailable() < blockSize: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return self.mutex.lock() fortune = instr.readQString() self.newFortune.emit(fortune) self.cond.wait(self.mutex) serverName = self.hostName serverPort = self.port self.mutex.unlock()
class DepthRenderThread(QThread): renderedImage = pyqtSignal() def __init__(self, w,h, l,r, parent=None): super(DepthRenderThread, self).__init__(parent) self.mutex = QMutex() self.condition = QWaitCondition() self.left = l self.right = r self.image = QImage(w, h, QImage.Format_Grayscale8) self.restart = False self.abort = False def __del__(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait() def updateImage(self): locker = QMutexLocker(self.mutex) if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def _updateImage(self): print("updating depth map") tmp = self.image.copy() tmp.fill(Qt.black) qp = QPainter(tmp) self.left.paintImage(qp, QRect(QPoint(0,0), tmp.size())) qp.end() ptr = tmp.constBits() ptr.setsize(tmp.byteCount()) left = np.array(ptr).reshape( tmp.height(), tmp.width(), 1) qp = QPainter(tmp) self.right.paintImage(qp, QRect(QPoint(0,0), tmp.size())) qp.end() ptr = tmp.constBits() ptr.setsize(tmp.byteCount()) right = np.array(ptr).reshape( tmp.height(), tmp.width(), 1) print("begin detection...") stereo = cv2.StereoBM.create(numDisparities=16, blockSize=15) # window_size = 3 # min_disp = 16 # num_disp = 112-min_disp # stereo = cv2.StereoSGBM.create( # minDisparity = min_disp, # numDisparities = num_disp, # blockSize = window_size, # uniquenessRatio = 10, # speckleWindowSize = 100, # speckleRange = 32, # disp12MaxDiff = 1, # P1 = 8*3*window_size**2, # P2 = 32*3*window_size**2 # ) #im = right im = stereo.compute(left, right) #pprint(im) im = (im/16).astype(np.uint8) print("convert result to QImage") # consider post processing: https://docs.opencv.org/3.1.0/d3/d14/tutorial_ximgproc_disparity_filtering.html self.mutex.lock() self.image = QImage(im.data, im.shape[1], im.shape[0], im.strides[0], QImage.Format_Grayscale8).copy() self.mutex.unlock() print("3d final image size "+str(self.image.width())+"x"+str(self.image.height())) def run(self): while not self.abort: self._updateImage() self.renderedImage.emit() self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock()