家庭燃气表微信抄表识别系统

news2024/7/4 4:59:31

1.背景需求

目前家里燃气度数的读数上报,每个月在社区微信群里面将手机拍摄的燃气表读数截图(加住址信息水印),发到群里给抄表员。

2.总体设计

在这里插入图片描述
在这里插入图片描述

设计目标
功能一:手机上随时可以远程采集读数图片(自动加住址信息水印),在微信上发送给社区抄表员。
功能二:每小时采集一次,统计燃气每日使用状况,对使用情况进行分析和预警(由于OCR还需要进一步提升识别能力,暂不实现)。
功能三:燃气漏气检测(因测试有一定危险,暂不实现)。

3.采集系统

使用树莓派,部署Docker环境。

3.1 功能描述

接收管理服务器实时采集请求,实现燃气表拍照的采集上报,摄像头采集之前要自动打开小夜灯照明,厨柜内较黑拍不清楚。

3.2 容器环境配置

3.2.1 Dockerfile文件

FROM ubuntu:latest
ENV LANG C.UTF-8
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update
RUN apt install -y openssh-client openssh-server
RUN apt-get install -y wget curl git telnet vim make gcc 
RUN apt-get install -y python3 python3-pip libpcre3 libpcre3-dev python3-opencv

RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
RUN echo "Port 8422" >> /etc/ssh/sshd_config
RUN echo 'root:cw' | chpasswd
RUN mkdir /var/run/sshd

EXPOSE 8422

RUN apt clean \
    && rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp* \
RUN apt autoremove

WORKDIR /tmp
RUN apt-get update
RUN apt-get upgrade -y
RUN apt install -y libusb-1.0-0-dev
RUN git clone https://github.com/mvp/uhubctl
WORKDIR /tmp/uhubctl
RUN make && make install

RUN pip3 install paho-mqtt pytest-shutil requests -i https://pypi.mirrors.ustc.edu.cn/simple/ 

WORKDIR /home
CMD ["/usr/sbin/sshd","-D"]

3.2.2 docker-compose.yaml文件

version: "3.0"
services:
  #燃气采集设备端
  #docker exec -it gas_meter_reading_t /bin/bash
  gas_meter_reading_t:
    build: .
    image: gas_meter_reading:v1
    container_name: gas_meter_reading_t
    working_dir: /home
#    devices:
#      - /dev/video0:/dev/video0
    ports:
      - 8422:8422
    volumes:
      - ./home:/home
    restart: always
    tty: true
    privileged: true

3.3 代码样例

3.3.1 控制USB小夜灯代码样例

#uhubctl 控制 usb 的供电情况,然后控制灯的状态
#控制命令:sudo uhubctl -l location -p port -a off
#location是USB集线起的位置,port是USB编号,off关闭,on打开;
uhubctl --help
uhubctl -l 2 -p 1 -a off
uhubctl -l 2 -p 1 -a on

3.3.2 摄像头拍摄代码样例

import cv2 as cv
cap = cv.VideoCapture(0)
if cap.isOpened():
    _, frame = cap.read()
	farm = cv.resize(frame, dsize = (1080,1080) )
 	cv.imwrite(r"/20231020/220301.jpg",farm)

4.管理系统

系统环境要求:LINUX系统,支持Docker环境。

4.1 容器环境配置

4.1.1 Dockerfile文件

FROM ubuntu
RUN apt update
RUN apt upgrade -y
RUN apt install -y wget libgl1 libglib2.0-dev python3 pip curl inetutils-ping graphicsmagick

# Install nvm
RUN apt install -y git
RUN git clone http://github.com/creationix/nvm.git /root/.nvm;
RUN chmod -R 777 /root/.nvm/;
RUN bash /root/.nvm/install.sh;
RUN export NVM_DIR="$HOME/.nvm";
RUN echo "[[ -s $HOME/.nvm/nvm.sh ]] && . $HOME/.nvm/nvm.sh" >> $HOME/.bashrc;

RUN bash -i -c 'nvm install 16'
RUN bash -i -c 'npm install -g pnpm'

CMD ["/bin/bash"]

4.1.2 Dockerfile_OCR

FROM ubuntu
RUN apt update
RUN apt upgrade -y
RUN apt install -y wget libgl1 libglib2.0-dev python3 pip curl inetutils-ping graphicsmagick

# Install nvm
RUN apt install -y git
RUN git clone http://github.com/creationix/nvm.git /root/.nvm;
RUN chmod -R 777 /root/.nvm/;
RUN bash /root/.nvm/install.sh;
RUN export NVM_DIR="$HOME/.nvm";
RUN echo "[[ -s $HOME/.nvm/nvm.sh ]] && . $HOME/.nvm/nvm.sh" >> $HOME/.bashrc;

RUN bash -i -c 'nvm install 16'
RUN bash -i -c 'npm install -g pnpm'

CMD ["/bin/bash"]

4.1.3 docker-compose.yaml

version: '3.3'
services:
  #Gas meter reading platform:燃气采集平台
  #docker exec -it gmrplat_t /bin/bash
  gmrplat_t:
    build: .
    image: gmrplat:v1
    volumes:
      - ./home:/home
    container_name: gmrplat_t
    ports:
      - 8477:8477
      - 8488:8488
    restart: always
    command: /bin/bash
    tty: true
    networks:
      back_net:
        ipv4_address: 172.77.1.5

  #百度AI/图像识别
  #docker exec -it paddle_ocr_t /bin/bash  
  paddle_ocr_t:
    container_name: paddle_ocr_t
    build:
      context: ./
      dockerfile: Dockerfile-OCR
    image: gmr_paddle_ocr
    volumes:
      - ./PaddleOCR:/PaddleOCR
    tty: true
    privileged: true
    restart: always
    command: /bin/bash
    networks:
      back_net:
        ipv4_address: 172.77.1.6
    
  #开源物联网MQTT服务器(https://www.emqx.com/)
  #初始用户名密码:admin/public
  #docker exec -it emq_t /bin/bash
  emq_t:
    container_name: emq_t
    image: emqx/emqx:5.3.0
    ports:
        - 1883:1883
        - 8083:8083
        - 8084:8084
        - 8883:8883
        - 18083:18083
    restart: always
    tty: true
    networks:
      back_net:
        ipv4_address: 172.77.1.7
  
  #开源数据库,兼容MYSQL
  mariadb_t:
    container_name: mariadb_t
    image: mariadb
    environment:
     - MYSQL_ROOT_PASSWORD=cjy
     - MYSQL_DATABASE=gmrplat
     - MYSQL_USER=cjy
     - MYSQL_PASSWORD=cjy
    restart: always
    networks:
      back_net:
        ipv4_address: 172.77.1.8
     
  #数据库WEB后台管理
  phpmyadmin_t:
    container_name: phpmyadmin_t
    image: phpmyadmin:5.2-apache
    ports:
     - 4090:80
    environment:
     - PMA_ARBITRARY=1
     - PMA_HOST=172.77.1.8
     - PMA_PORT=3306
     - PMA_USER=root
     - PMA_PASSWORD=cjy
    restart: always
    networks:
      back_net:
        ipv4_address: 172.77.1.9

#自定义容器网络
networks:
  back_net:
    ipam:
      driver: default
      config:
        - subnet: 172.77.1.0/24

4.2 图像识别系统

百度开源AI:https://github.com/PaddlePaddle/PaddleOCR
在这里插入图片描述照片OCR识别样例代码

from paddleocr import PaddleOCR, draw_ocr
ocr = PaddleOCR(use_angle_cls=True, lang="en")
img_path = './ppocr_img/imgs/11.jpg'
result = ocr.ocr(img_path, cls=True)
for idx in range(len(result)):
    res = result[idx]
    for line in res:
        print(line)

4.3 远程抄表前台系统

主要代码,不是全部。

<script setup>
import { ref } from 'vue'
import 'weui';
import axios from 'axios';

async function get_gmr_img() {
    console.log('get_gmr_img')
    try{
        let res = await axios.get('/api/gmr_img_now');
        console.log(res);
        let result = res.data;
        console.log(result);

        res = await axios.get('/api/gmr_get_last_img');
        console.log(res);
        result = res.data[0];
        console.log(result.img_name);
        const imgUrl = 'http://58.212.21.66:8488/images/mask_' + result.img_name;
        document.getElementById('gmr_img').src = imgUrl
    }catch{
        console.log('请求失败');
    }
}
</script>

<template>
    <img id="gmr_img" src="/favicon.ico" class=gmr_img>
    <button class="weui-btn weui-btn_primary" @click="get_gmr_img">立即更新</button>
    <div style="text-align:center;" id="actionsheet1" class="weui_actionsheet_cell">长按燃气表图片2秒转发给抄表员</div>
</template>

<style scoped>
.gmr_img {
    width:  100vw;
    height: 80vh;
}
</style>

4.4 远程抄表后台系统

CREATE TABLE `gmrinfo` (
  `id` bigint(12) NOT NULL,
  `gather_time` datetime NOT NULL DEFAULT current_timestamp(),
  `img_name` varchar(30) NOT NULL,
  `img_ocr` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
const {promises:fs} = require("fs");
const moment = require('moment');
const Koa    = require('koa');
const Router = require('koa-router');
const koa_static  = require('koa-static');
const bodyParser  = require('koa-bodyparser');
const mqtt        = require('mqtt');
const axios       = require('axios');
const knex   = require('knex'); //https://knexjs.org/
const gm     = require('gm');

const OCR_SERVER_IP    = '172.77.1.6'
const OCR_SERVER_PORT  = 8466

const MQTT_SERVER_IP   = '172.77.1.7'
const MQTT_SERVER_PORT = 1883

const DB_SERVER_IP     = '172.77.1.8'
const DB_USER          = 'cjy'
const DB_PWD           = 'cjy'
const DB_NAME          = 'gmrplat'

const GMRPLAT_SERVER_PORT = 8488

const db = knex({
  client: "mysql2",
  connection: {
    host: DB_SERVER_IP,
    port: 3306,
    user: DB_USER,
    password: DB_PWD,
    database: DB_NAME,
  },
});

const WWWROOT = __dirname + '/public'
const IMGDIR  = WWWROOT + '/images/'

//图像识别
const GMRToOCR = async (imgfile) => {
    const url = "http://" + OCR_SERVER_IP + ":" + OCR_SERVER_PORT + "/GMROCR"
    const bitmap = await fs.readFile(imgfile);
    const adata = {
        request_id: '001',
        img_base64: ''
    }
    adata['img_base64'] = Buffer.from(bitmap).toString('base64');
    const res = await axios.post(url, adata);
    console.log(res.data)
    console.log(res.data.ocr_res)
    return res.data
}

const client = mqtt.connect("mqtt://" + MQTT_SERVER_IP + ":" + MQTT_SERVER_PORT);
client.subscribe("gmrdev/fixedtime")

client.on('message', async (topic, payload) => {
  console.log('Received Message:', topic);
  const base64EncodedfileData = payload.toString();
  const fileDataDecoded = Buffer.from(base64EncodedfileData,'base64');
  const img_name = moment(Date.now()).format('YYYYMMDDHHmmss');
  fs.writeFile(IMGDIR + img_name + ".jpg", fileDataDecoded, err => {})
  await gmr_add_img(img_name + ".jpg")

  gm(IMGDIR + img_name + ".jpg")
    .stroke("blue") //字体外围颜色
    .fill("blue")   //字体内围颜色(不设置默认为黑色)
    .font("./AlibabaPuHuiTi-3-65-Medium.ttf", 60) //字库所在文件夹和字体大小
    .drawText(50,50, img_name + "\nXX街道X小区X幢X室")
    .write(IMGDIR + "mask_" + img_name + ".jpg", function (err) {
       if (!err) console.log('gm_ok');
       else console.log(err);
  });
  //const ocr_res = await GMRToOCR(IMGDIR + img_name + ".jpg");
});

const app_http   = new Koa()
app_http.use(bodyParser());

app_http.use(async (ctx, next) =>{
    await next();
    ctx.set("Access-Control-Allow-Origin", "*");
    ctx.set("Access-Control-Allow-Headers", "Content-Type");
    ctx.set("Access-Control-Allow-Methods", "*");
});

app_http.use(koa_static(WWWROOT, {
    index: true, 
    hidden: false,
    defer: true
}))

const gmr_add_img = async (img_name) => {
    console.log('gmr_add_img:' + img_name)
    await db('gmrinfo').insert({img_name: img_name})
}

const gmr_img_now = async (ctx) => {
    console.log('gmr_img_now')
    client.publish('gmrplat/nowtime', 'now')
    ctx.body = 'OK'
}

const gmr_get_last_img = async (ctx) => {
    let result = await db("gmrinfo").select(["id", "gather_time","img_name","img_ocr"]).orderBy('id', 'desc').limit(1)
    console.log(result)
    ctx.body = result
}

const router  = new Router();
router.get('/api/gmr_img_now', gmr_img_now);
router.get('/api/gmr_get_last_img', gmr_get_last_img);

app_http.use(router.routes());

app_http.listen(GMRPLAT_SERVER_PORT, '0.0.0.0', () => {
    console.log(`服务启动:http://58.212.21.66:${GMRPLAT_SERVER_PORT}`);
})

5.系统演示

配套代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122070.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins环境部署与任务构建

一、CI/CD 1、CI/CD 概念&#xff1a; CI/CD 是一种软件开发和交付方法&#xff0c;旨在加速应用程序的开发、测试和部署过程&#xff0c;以提高软件交付的质量和效率。 (1) 持续集成 (CI Continuous Integration): 持续集成是开发团队频繁集成其代码更改的过程。开发者将其…

2023Jenkins连接k8s

首先配置k8s config文件 1.方式获取k8s密钥 cat .kube/config 2.导出方式或者密钥 kubectl config view --raw > k8s-config-admin pipeline {agent {kubernetes {yaml apiVersion: v1kind: Podmetadata:labels:some-label: devopsspec:containers:- name: dockerimage: d…

SpringBoot 第一个接口编写

RestController //表示该类为请求处理类public class HttpDeal {RequestMapping("/login")//这个方法处理哪一个地址过来的请求public String hello(){return "返回给浏览器";}}

【网络协议】聊聊网关 NAT机制

再宿舍的时候&#xff0c;其实只能通过局域网进行处理&#xff0c;但是如果接入互联网&#xff0c;一般是配置路由器当然还有网关。 MAC头和IP头的细节 一旦配置了IP地址和网关&#xff0c;就可以制定目标地址进行访问。 MAC头主要信息目标和源MAC地址&#xff0c;以及协议类…

二、BurpSuite Intruder暴力破解

一、介绍 解释&#xff1a; Burp Suite Intruder是一款功能强大的网络安全测试工具&#xff0c;它用于执行暴力破解攻击。它是Burp Suite套件的一部分&#xff0c;具有高度可定制的功能&#xff0c;能够自动化和批量化执行各种攻击&#xff0c;如密码破解、参数枚举和身份验证…

031-第三代软件开发-屏幕保护

第三代软件开发-屏幕保护 文章目录 第三代软件开发-屏幕保护项目介绍屏幕保护 关键字&#xff1a; Qt、 Qml、 MediaPlayer、 VideoOutput、 function 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#…

SIEMENS S7-1200 汽车转弯灯程序 编程与分析

公告 项目地址:https://github.com/MartinxMax/SIEMENS-1200-car_turn_signal 分析 题目: 画IO分配表 输入输出m3.0左转弯开关q0.0左闪灯m3.1右转弯开关q0.1右闪灯m3.2停止开关 博图V16配置 设置PLC的IP地址 允许远程通信访问 将HMI设备拖入 注意,我们这边选择的是HMI连接…

Leetcode——二维数组及滚动数组练习

118. 杨辉三角 class Solution { public:vector<vector<int>> generate(int numRows) {// 定义二维数组vector<vector<int>> num(numRows);for(int i0;i<numRows;i){//这里是给内层vector定义大小。默认是0,这里n是个数&#xff0c;不是值num[i].re…

【Java基础面试四十二】、 static修饰的类能不能被继承?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a; static修饰的类能不能被…

物联网AI MicroPython传感器学习 之 RTC时钟模块

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 DS1302 是DALLAS 公司推出的涓流充电时钟芯片&#xff0c;内含有一个实时时钟/日历和31字节静态RAM&#xff0c;实时时钟/日历电路提供秒、分、时、日、周、月、年的信息&#xff0c;每月的天数…

驱动开发2 CoetexA7核 字符设备驱动(LED亮灯)(单独映射寄存器实现+封装结构体映射实现)

一、单独映射寄存器实现 可参考arm点灯C语言 cortex-A7核 点LED灯 &#xff08;附 汇编实现、使用C语言 循环实现、使用C语言 封装函数实现【重要、常用】&#xff09;-CSDN博客 1 应用程序 test.c #include <stdio.h> #include <sys/types.h> #include <sys/s…

云服务器搭建Hadoop分布式

文章目录 1.服务器配置2.Java环境3. 安装Hadoop4. 集群配置5. 编写集群的启动脚本 1.服务器配置 服务器主机名配置115.157.197.82s110核115.157.197.84s210核115.157.197.109s310核115.157.197.31s410核115.157.197.60gracal10核 所有的软件安装在/opt/module下&#xff0c;软…

python生成的报告中绘制了多张图,但最后都混合到一起了

问题来源&#xff1a; 用python生成的报告中&#xff0c;存在三张图&#xff0c;第一个张图是正常的&#xff0c; 后面的图都是不正常的&#xff0c;全都是多张图混合而成的&#xff0c;这是为什么呢&#xff1f; 三段代码均是下述调用方式 import matplotlib.pyplot as plt pl…

biquad滤波器的设计

1.介绍 Biquad滤波器是一种常用的数字滤波器结构&#xff0c;它使用二阶差分方程&#xff08;difference equation&#xff09;来实现滤波功能。它得名于其包含两个极点&#xff08;poles&#xff09;和一个零点&#xff08;zero&#xff09;。 双二阶滤波器(biquad)是最常用…

DALL·E 3:OpenAI的革命性图像生成模型与ChatGPT的融合

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

贪吃蛇项目实践

游戏背景&#xff1a; 贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯⽅块&#xff0c;扫雷等游戏位列经典游戏的⾏列。 实现基本的功能&#xff1a; 贪吃蛇地图绘制 蛇吃⻝物的功能 &#xff08;上、下、左、右⽅向键控制蛇的动作&#xff09; 蛇撞墙死亡 蛇撞⾃⾝死亡 计…

Leetcode 454 四数相加II(哈希表 + getOrDefault方法用于获取Map中指定键的值,如果键不存在,则返回一个默认值)

Leetcode 454 四数相加II&#xff08;哈希表&#xff09; 解法1 HashMap getOrDefault方法 解法1 HashMap getOrDefault方法 【HashMap】 【⭐️HashMap常用操作】 创建HashMap&#xff1a;HashMap<Integer, Integer> hash new HashMap<>(); 向HashMap添加元素…

vant组件是使用?

首先 在vue项目中使用的时候 要先下载组件 使用npm安装 # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant# Vue 2 项目&#xff0c;安装 Vant 2 npm i vantlatest-v2 使用yarn安装或pnpm # 通过 yarn 安装 yarn add vant# 通过 pnpm 安装 pnpm add vant 在框架中引入即…

No170.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

Elasticsearch的聚集统计,可以进行各种统计分析

说明&#xff1a; Elasticsearch不仅是一个大数据搜索引擎&#xff0c;也是一个大数据分析引擎。它的聚集(aggregation)统计的REST端点可用于实现与统计分析有关的功能。Elasticsearch提供的聚集分为三大类。 度量聚集(Metric aggregation)&#xff1a;度量聚集可以用于计算搜…