萤石云摄像头api+百度飞桨OCR 实现非智能电表读表

 功能实现远程读取非智能电表的用电量,并记录到Excel,每月15号定时统计计算,发送电量到微信,

上代码,功能有打开浏览器并截图,ocr识别电表读数,记录到Excel,和上个月做对比,计算出一个月的用电量。

import datetime
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image, ImageGrab
import openpyxl
from openpyxl import Workbook
import pygetwindow as gw
from pywinauto import Application
import time
import requests
import json
import re
from requests.exceptions import HTTPError, RequestException
def send_request(method, url, headers=None, data=None, json_data=None):
    """通用请求函数"""
    try:
        response = requests.request(method, url, headers=headers, data=data, json=json_data, allow_redirects=False)
        response.raise_for_status()
        return response
    except HTTPError as http_err:
        print(f'HTTP error occurred: {http_err}')
    except RequestException as req_err:
        print(f'Request error occurred: {req_err}')
    return None
def send_wx_message(content, contenttype):
    """发送微信消息"""
    url = "http://127.0.0.1:5555/api/sendATMsg"
    payload = {
        "para": {
            "id": "{{date_time}}",
            "roomid": "null",
            "wxid": "12298079682@chatroom",
            #"wxid": "38950634091@chatroom",
            "content": content,
            "type": contenttype,
            "nickname": "三块钱",
            "ext": "null"
        }
    }
    headers = {'Content-Type': 'application/json'}
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    if response:
        print(response.text)

def capture_window_by_keyword(keyword, region=None, output_file='selected_window_screenshot.png'):
    windows = gw.getAllWindows()
    matched_windows = [window for window in windows if keyword.lower() in window.title.lower()]
    if not matched_windows:
        print(f'No windows found with the keyword: {keyword}')
        return
    selected_window = matched_windows[0]
    app = Application().connect(handle=selected_window._hWnd)
    app.top_window().set_focus()
    time.sleep(1)
    x1, y1 = selected_window.left, selected_window.top
    x2, y2 = selected_window.right, selected_window.bottom
    if region:
        region_x1, region_y1, region_x2, region_y2 = region
        x1 += region_x1
        y1 += region_y1
        x2 = x1 + (region_x2 - region_x1)
        y2 = y1 + (region_y2 - region_y1)
    bbox = (x1, y1, x2, y2)
    screenshot = ImageGrab.grab(bbox)
    screenshot.save(output_file)
    print(f'Screenshot saved to {output_file}')

def extract_numbers(string):
    numbers = re.findall(r'\d+', string)
    return ''.join(numbers)

def perform_ocr(img_path):
    ocr = PaddleOCR(use_angle_cls=True, lang="ch")
    result = ocr.ocr(img_path, cls=True)
    for idx in range(len(result)):
        res = result[idx]
        for line in res:
            print(line)
    result2 = result[0]
    image = Image.open(img_path).convert('RGB')
    boxes = [line[0] for line in result2]
    txts = [line[1][0] for line in result2]
    scores = [line[1][1] for line in result2]
    im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf')
    im_show = Image.fromarray(im_show)
    #im_show.save('3.jpg')
    
    count = len(result[0])
    print(count)
    
    start_index = None
    end_index = None
    target_text = None
    
    for i, line in enumerate(result[0]):
        text = line[1][0]
        if text == '十':
            start_index = i
        elif text == '★':
            end_index = i
        elif start_index is not None and end_index is None:
            target_text = text
            box = line[0]
            score = line[1][1]
            break
    
    if target_text:
        print(f"识别文本: {target_text}, 置信度: {score}")
        print(f"识别文本: {extract_numbers(target_text)}, 置信度: {score}")
        im_show = draw_ocr(image, [box], [target_text], [score], font_path='./fonts/simfang.ttf')
        im_show = Image.fromarray(im_show)
        im_show.save('extracted_target_text.png')
        #im_show.show()
        return extract_numbers(target_text)
    else:
        print("未找到目标文本")
        return None

def read_meter(file_path):
    try:
        wb = openpyxl.load_workbook(file_path)
        sheet = wb.active
        if sheet.max_row > 1:
            last_row = sheet[sheet.max_row]
            last_date = last_row[0].value
            last_reading = last_row[1].value
            if last_date and last_reading is not None:
                last_reading = int(last_reading)
                return last_date, last_reading
            else:
                return None, 0
        else:
            return None, 0
    except FileNotFoundError:
        return None, 0

def write_meter(file_path, date, reading):
    try:
        wb = openpyxl.load_workbook(file_path)
    except FileNotFoundError:
        wb = Workbook()
        sheet = wb.active
        sheet.append(["日期", "读数"])
    sheet = wb.active
    sheet.append([date, reading])
    wb.save(file_path)

def calculate_usage(file_path, current_date, current_reading):
    last_date, last_reading = read_meter(file_path)
    usage = current_reading - last_reading
    write_meter(file_path, current_date, current_reading)
    return last_date, last_reading, current_date, current_reading, usage

# 主程序
img_path = 'D:\电表\selected_window_screenshot.png'
file_path = 'D:\电表\meter_readings.xlsx'

# 从图像中提取电表读数
text = perform_ocr(img_path)
if text is not None:
    try:
        current_reading = int(text)
        current_date = datetime.datetime.now()
        last_date, last_reading, current_date, current_reading, usage = calculate_usage(file_path, current_date, current_reading)
        print(f"上次读数是在 {last_date.strftime('%Y-%m-%d')},读数为 {last_reading} 度。")
        print(f"当前读数是在 {current_date.strftime('%Y-%m-%d')},读数为 {current_reading} 度。")
        print(f"这段时间的用量为 {usage } 度。")
        send_wx_message(f"上次读数是在 {last_date.strftime('%Y-%m-%d')},读数为 {last_reading} 度。\n当前读数是在 {current_date.strftime('%Y-%m-%d')},读数为 {current_reading} 度。\n这段时间的用量为 {usage } 度。电费费用为:{usage*1}元" ,555)
        send_wx_message(f"D:/电表/3.jpg" ,500)
    except ValueError:
        print("无法将识别结果转换为整数。")

萤石云摄像头,申请appKey和appSecret 获取摄像头直播地址,如何生成html文件,预览视频

import requests
import json
def getysyTaken():
    url = "https://open.ys7.com/api/lapp/token/get?appKey=6980b***************d72b&appSecret=7ab3*********0b72"

    payload = {}
    files={}
    headers = {}

    response = requests.request("POST", url, headers=headers, data=payload, files=files, allow_redirects=False)

    print(response.text)
    response = response.json()
    return (response['data']['accessToken'])

access_token = getysyTaken()
html_content = f'''<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>摄像头</title>
    <script src="ezuikit.js"></script>
    <style>
        html,body {{
            padding: 0;
            margin: 0;
            text-align: center;
            background: #00000080;
            overflow: hidden;
        }}
    </style>
</head>
<body>
    <div id="playWind"></div>
    <script>
        var domain = "https://open.ys7.com";
        var EZOPENDemo;
        window.EZOPENDemo = EZOPENDemo;
        var width = document.documentElement.clientWidth;
        var height = document.documentElement.clientHeight;
        const ezopenInit = () => {{
            EZOPENDemo = new EZUIKit.EZUIKitPlayer({{
                id: 'playWind',
                width: '800',
                height: '500',
                template: "simple",
                url: "ezopen://open.ys7.com/798797360/1.live",
                accessToken: "{access_token}"
            }});
        }}
        ezopenInit();
    </script>
</body>
</html>
'''

# 将HTML内容写入文件
with open('index.html', 'w', encoding='utf-8') as file:
    file.write(html_content)

print("index.html 文件已生成")

好的,实现安卓app调取萤石云摄像头需要用到萤石云SDK。下面是一个简单的示例: 1. 在萤石云开发者中心申请AppKey和AppSecret,以获取SDK的使用权限。 2. 将萤石云SDK添加到您的项目中。您可以通过Gradle添加以下依赖: ```groovy implementation 'com.videogo:ezopenSDK:5.0.0' ``` 3. 在您的代码中调用SDK接口,实现调取摄像头的功能。以下是一个示例代码: ```java import com.videogo.openapi.EZOpenSDK; import com.videogo.openapi.bean.EZAccessToken; import com.videogo.openapi.bean.EZCameraInfo; import com.videogo.openapi.callback.OnEZAccessTokenCallback; import com.videogo.util.LogUtil; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final String APP_KEY = "您的AppKey"; private static final String APP_SECRET = "您的AppSecret"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化EZOpenSDK EZOpenSDK.showSDKLog(true); EZOpenSDK.enableP2P(true); EZOpenSDK.initLib(this, APP_KEY); // 获取AccessToken EZOpenSDK.getInstance().openLoginPage(new OnEZAccessTokenCallback() { @Override public void onAccessTokenResult(final EZAccessToken ezAccessToken) { // 获取AccessToken成功 LogUtil.i(TAG, "onAccessTokenResult: " + ezAccessToken.getAccessToken()); // 获取摄像头信息 EZOpenSDK.getInstance().getCameraInfo("您的摄像头序列号", new OnGetCameraInfoListener() { @Override public void onGetCameraInfoSuccess(EZCameraInfo ezCameraInfo) { // 获取摄像头信息成功 LogUtil.i(TAG, "onGetCameraInfoSuccess: " + ezCameraInfo.getCameraName()); // 打开实时预览页面 EZOpenSDK.getInstance().openCameraLivePlayPage(ezCameraInfo.getCameraId(), 1); } @Override public void onGetCameraInfoError(ErrorInfo errorInfo) { // 获取摄像头信息失败 LogUtil.e(TAG, "onGetCameraInfoError: " + errorInfo.getErrorCode()); } }); } @Override public void onAccessTokenError(ErrorInfo errorInfo) { // 获取AccessToken失败 LogUtil.e(TAG, "onAccessTokenError: " + errorInfo.getErrorCode()); } }, APP_KEY, APP_SECRET); } @Override protected void onDestroy() { super.onDestroy(); // 释放EZOpenSDK资源 EZOpenSDK.getInstance().releaseLib(); } } ``` 这段代码的作用是获取萤石云的AccessToken,然后获取指定摄像头的信息,最后打开实时预览页面。请将代码中的“您的AppKey”、“您的AppSecret”和“您的摄像头序列号”替换为实际的值。 需要注意的是,打开实时预览页面需要相应的权限,例如网络访问和摄像头访问权限。您需要在AndroidManifest.xml文件中添加以下权限声明: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> ``` 这样,就可以实现安卓app调取萤石云摄像头的功能了。如果您需要添加更多的功能,例如录制视频或拍照等,可以参考萤石云SDK相关文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三块钱0794

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值