--- disqus: ahb0222 GA : G-VF9ZT413CG --- > [color=#40f1ef][name=LHB阿好伯, 2021/07/16][:earth_africa:](https://www.facebook.com/LHB0222/) [TOC] Python結合MQTT與Tesseract OCR技術 可以實現設備主機數值截圖的傳輸與數字辨識 透過這項技術,您可以將設備的數據截圖傳送至Node-RED進行處理 並利用本地化的Tesseract OCR進行數字辨識 (取代之前我使用的[OCR.space服務](https://ocr.space/OCRAPI)) 可以避免又遇到伺服器出現問題或免費使用的次數限制 ![image](https://hackmd.io/_uploads/Sk9SdjFU0.png) ![image](https://hackmd.io/_uploads/HkZuYjF8A.png) 利用node-red設定當設備的強度變化低於設定值時 系統會自動發送Line通知 同時還可以繪製趨勢圖以觀察數據變化。 解決了許多設備軟體缺乏通知功能的問題 避免了人員無法隨時關注或及時發現遠端設備狀態的困境 ![image](https://hackmd.io/_uploads/ryQBcotLC.png) 以下是程式的實現步驟和主要功能: 連接MQTT Broker:設定連接和斷開連接的處理函數,確保穩定連線。 接收影像訊息:訂閱特定主題以接收影像訊息,並將接收到的影像數據解碼保存為圖片檔案。 影像處理:檢查影像最上面三行的平均亮度,判斷是否需要進行黑白反轉,以便於OCR辨識 (使用過程中發現Tesseract OCR辨識白底黑字比較正常) 傳送辨識結果:將辨識出的數字結果發布到對應的MQTT主題,以便進一步處理。 ```python= # sudo apt install tesseract-ocr # sudo apt install libtesseract-dev import base64 import cv2 import pytesseract from PIL import Image, ImageOps import io from paho.mqtt import client as mqtt_client import random from datetime import datetime import logging import numpy as np # 設置 logging 配置 logging.basicConfig(filename='mqtt_ocr.log', level=logging.INFO, format='%(asctime)s %(message)s') # MQTT 配置 broker = 'broker.emqx.io' port = 1883 topic = "MQTTin/image-topic/#" #MQTT訂閱的路徑 client_id = f'subscribe-{random.randint(0, 100)}' ocr_topic_base = "MQTTout/ocr-topic/" #OCR結果發佈的路徑 is_connected = False def log_with_timestamp(message): timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') logging.info(f"{message}") def connect_mqtt(): def on_connect(client, userdata, flags, rc): global is_connected if rc == 0: is_connected = True log_with_timestamp("Connected to MQTT Broker!") client.subscribe(topic) else: log_with_timestamp(f"Failed to connect, return code {rc}") def on_disconnect(client, userdata, rc): global is_connected is_connected = False log_with_timestamp(f"Disconnected from MQTT Broker, return code {rc}") if rc != 0: log_with_timestamp("Unexpected disconnection.") client = mqtt_client.Client(client_id) client.on_connect = on_connect client.on_disconnect = on_disconnect client.connect(broker, port) return client def on_message(client, userdata, msg): log_with_timestamp(f"Received message on topic {msg.topic}") # 解碼並保存影像 try: img_data = base64.b64decode(msg.payload) image = Image.open(io.BytesIO(img_data)) image.save("received_image.png") except Exception as e: log_with_timestamp(f"Error decoding image: {e}") return # 讀取影像並判斷最上面三行像素的平均亮度 try: image = Image.open("received_image.png").convert("L") image_np = np.array(image) top_three_rows = image_np[:3, :] # 取得最上面三行 mean_brightness = np.mean(top_three_rows) log_with_timestamp(f"Mean brightness of top three rows: {mean_brightness}") # 如果背景為黑色,則進行黑白反轉 if mean_brightness < 128: inverted_image = ImageOps.invert(image) inverted_image.save("processed_image.png") else: image.save("processed_image.png") except Exception as e: log_with_timestamp(f"Error processing image: {e}") return # 讀取處理後的影像 image = cv2.imread("processed_image.png") if image is None: log_with_timestamp("Error reading image") return # 進行 OCR 辨識 try: # 設定只辨識數字和小數點 config = '--psm 7 -c tessedit_char_whitelist=0123456789.' text = pytesseract.image_to_string(image, config=config) except Exception as e: log_with_timestamp(f"Error during OCR: {e}") return # 生成回傳的主題 ocr_topic = ocr_topic_base + msg.topic.split('/')[-1] # 發布 OCR 結果 client.publish(ocr_topic, text) log_with_timestamp(f"Published OCR result to {ocr_topic}: {text}") def run(): client = connect_mqtt() client.on_message = on_message while True: if not is_connected: client.reconnect() client.loop_forever() if __name__ == '__main__': run() ``` 🌟全文可以至下方連結觀看或是補充 全文分享至 https://www.facebook.com/LHB0222/ https://www.instagram.com/ahb0222/ 有疑問想討論的都歡迎於下方留言 喜歡的幫我分享給所有的朋友 \o/ 有所錯誤歡迎指教 # [:page_with_curl: 全部文章列表](https://hackmd.io/@LHB-0222/AllWritings) ![](https://i.imgur.com/nHEcVmm.jpg)