---
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)