From 056e3a0b8cd2bfe5c1c7b48ef8da136734088673 Mon Sep 17 00:00:00 2001 From: yq183 <645046984@qq.com> Date: Tue, 1 Oct 2024 21:09:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E7=BD=91=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 3 + .idea/algorithm.iml | 8 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + gengbao.py | 462 ++++++++++++++++++ internalNet/internalNet.py | 170 +++++++ pi.py | 16 + 9 files changed, 686 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/algorithm.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 gengbao.py create mode 100644 internalNet/internalNet.py create mode 100644 pi.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/algorithm.iml b/.idea/algorithm.iml new file mode 100644 index 0000000..5410dcd --- /dev/null +++ b/.idea/algorithm.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f0589af --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2ba6d76 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/gengbao.py b/gengbao.py new file mode 100644 index 0000000..87ed862 --- /dev/null +++ b/gengbao.py @@ -0,0 +1,462 @@ +import datetime +import math +import os +import signal +import sys +import threading +import re +import uuid +import tempfile +import pyexiv2 +import numpy as np + +import requests +from PIL import Image + +from numpy import arctan +import cv2 +from math import tan, cos, sin +import oss2 +import paho.mqtt.client as mqtt +import concurrent.futures +import json + + + +# 客户端id +client_id='python_gengbao' +# 订阅主题 +longandlat_mqtt ='task/image/gps/custon' +# 订阅主题 +appTwo ='task/image/disobey/handle' +# 订阅主题 +weijian ='task/image/pixel/custon' + +# 发布通知主题 +pushNoticeTopic ='task/image/disobey/confirm' + + +access_key = "LTAI5tMDFvYZRvrJfK7HeuEm" +secret_key = "kP7ueRlhLbM9mvkaLtHfcje3GxgawH" +endpoint = "oss-cn-hangzhou.aliyuncs.com" +bucket_name = "yq-dajiang" + + + +auths = oss2.Auth(access_key, secret_key) +bucket = oss2.Bucket(auths, endpoint, bucket_name) +# 根据像素坐标生成图片和经纬度,放入集合中,返回到前端 + + +client = mqtt.Client(client_id=client_id) +#截图 +def crop_image(input_image,center_x,center_y): + print(center_x,center_y) + #固定截图尺寸 1000*1000 + l_x = 0 + l_y=0 + r_x=1000 + r_y=1000 + if center_x>500: + l_x=center_x-500 + r_x=center_x+500 + if r_x>=4000: + r_x=4000 + l_x=3000 + + if center_y>500: + l_y=center_y-500 + r_y=center_y+500 + if r_y>=3000: + r_y=3000 + l_y=2000 + print((l_x,l_y),(r_x,r_y)) + # 截取指定区域图像 + cropped_image = input_image[l_y:r_y, l_x:r_x] + return np.array(cropped_image) +#计算两个经纬度之间的距离,用于计算长宽 +def dimension(jingduA, weiduA,jingduB, weiduB): + R = 6371.393 + Pi = math.pi + + a = (math.sin(math.radians(weiduA / 2 - weiduB / 2))) ** 2 + b = math.cos(weiduA * Pi / 180) * math.cos(weiduB * Pi / 180) * ( + math.sin((jingduA / 2 - jingduB / 2) * Pi / 180)) ** 2 + dimension = 2 * R * math.asin((a + b) ** 0.5) * 1000 + return dimension + +def sum(focalLength,x,altitude): + width=4000 + #靶面宽 + ba=6.2 + #实际长度 + wr=(x*altitude*ba)/(focalLength*width) + return wr + +def longandlat(pixel_x,pixel_y,imageMap): + + # 焦距 + focalLength =float(imageMap["focalLength"]) + # 经纬度 + longitude_str=imageMap["longitude"] + latitude_str = imageMap["latitude"] + # 使用正则表达式提取度、分和秒的数值 + pattern = r"(\d+)° (\d+)' ([\d.]+)\"" + longitude_match = re.match(pattern, longitude_str) + latitude_match = re.match(pattern, latitude_str) + print(longitude_match) + print(type(longitude_match)) + + # 度 + lg_du =int(longitude_match.group(1)) + # 分 + lg_fen =int(longitude_match.group(2)) + # 秒 + lg_seconds = float(longitude_match.group(3)) + + # 度 + la_du = int(latitude_match.group(1)) + # 分 + la_fen = int(latitude_match.group(2)) + # 秒 + la_seconds =float(latitude_match.group(3)) + + + # 海拔 + altitude = float(imageMap["altitude"]) + # 图片宽高 + width =float(imageMap["width"]) + height =float(imageMap["height"]) + + + # 中点坐标 + x, y = width // 2, height // 2 + # 通过勾股定理可以计算出 1/2.3 英寸对角线的长度大约为 4.54 毫米。 + + D = 2 * tan(arctan(9.826 / 2 / focalLength) / 2) * altitude + + # 因此,每个像素所代表的实际距离为(米): + # p =(9.826*altitude)/(width*focalLength) + + p = D / width + # 经度每秒代表的距离 m + # 纬度每秒代表的距离 m + lat_p = 23.6 + long_p = 30.9 + + pie=float(imageMap["xmpProperties"]) + + if pie < 0: + pie = -180 + abs(pie) + else: + pie = 180 - pie + # z转换已中心点为原点的坐标体系 + px = (pixel_x - x) + py = (y - pixel_y) + + a = math.radians(pie) + + # 坐标体系旋转后所得到的坐标 + c_a_x = cos(a) * px - sin(a) * py + c_a_y = sin(a) * px + cos(a) * py + + ys = c_a_y * p / lat_p + xs = c_a_x * p / long_p + + la_seconds += ys + lg_seconds += xs + + longitude_x = lg_du + lg_fen / 60.0 + lg_seconds / 3600.0 + + latitude_y = la_du + la_fen / 60.0 + la_seconds / 3600.0 + return longitude_x ,latitude_y,focalLength,altitude + + + +def upload_image_to_oss(imgeName,data): + + # imgeName 文件名 列:python/img.jpg + bucket.put_object(imgeName, data) + # 将对象权限设置为公共读,以便通过URL访问上传的图像 + bucket.put_object_acl(imgeName, oss2.OBJECT_ACL_PUBLIC_READ) + # 获取对象URL + url = bucket.sign_url("GET", imgeName,3600) # URL有效期为1小时 + return url.split('?')[0] + +# 连接回调函数 +def on_connect(client, userdata, flags, rc): + """一旦连接成功, 回调此方法""" + rc_status = ["连接成功", "协议版本错误", "无效的客户端标识", "服务器无法使用", "用户名或密码错误", "无授权"] + print("connect:", rc_status[rc]) + topics = [str(weijian), str(longandlat_mqtt), str(appTwo)] + # 要订阅的主题列表 + for topic in topics: + # 订阅主题 + print("订阅主题:", topic) + client.subscribe(topic) +def compute(re): + if "sourceImgUrl" in re and "pixelCoordinate" in re: + sourceImgUrl = re["sourceImgUrl"] + mateSourceImgUrl = re["mateSourceImgUrl"] + pixelCoordinate = re["pixelCoordinate"] + imageMap = re["imageMap"] + maplist=[] + # 如果image1和image2都不为空,执行相关操作 + # 指向算法比对,获取图片z + if pixelCoordinate: + coordinateList = json.loads(pixelCoordinate) + # 指向算法比对,获取图片 + if len(coordinateList) != 0: + # 从URL加载图像 + resp = requests.get(sourceImgUrl) + # 创建临时文件 + # 创建临时文件 + temp_file = tempfile.NamedTemporaryFile(delete=False) + temp_file.write(resp.content) + temp_file.close() + + + # 前端缩放了,比例是:scale=4 + for item in coordinateList: + lef_x = item["lef_x"] + lef_y = item["lef_y"] + right_x = item["right_x"] + right_y = item["right_y"] + # 将比例还原 + scale = 4 + lef_x = int(lef_x * scale) + lef_y = int(lef_y * scale) + right_x = int(right_x * scale) + right_y = int(right_y * scale) + x=right_x-lef_x + y=right_y-lef_y + # 中心坐标 + # 计算矩形框的中心点坐标 + center_x = int((lef_x + right_x) / 2) + center_y = int((lef_y + right_y) / 2) + # 经纬度转换 + long, lat ,focalLength,altitude= longandlat(center_x, center_y, imageMap) + img_array = np.frombuffer(resp.content, np.uint8) + # 将矩形框绘制到图片上 + img_copy = cv2.imdecode(img_array, cv2.IMREAD_COLOR) + # 在图像上绘制矩形框 + cv2.rectangle(img_copy, (lef_x,lef_y), (right_x,right_y), (0, 255, 255), 10) + # OpenCV图像对象转换为字节流格式。 + _, buffer = cv2.imencode('.jpg', img_copy) + img_bytes = buffer.tobytes() + # 文件名称 + unique_id = str(uuid.uuid4()) + imgName = 'python/' + unique_id + "违建图.jpg" + # 将图片上传到阿里云OSS + url = upload_image_to_oss(imgName, img_bytes) + + # 获取长 + w = sum(focalLength,x,altitude) + # 获取宽 + h = sum(focalLength,y,altitude) + # 计算矩形面积并保留两位小数 + area = round(w * h, 2) + + #截图 对比图放大 + cropped_image1=crop_image(img_copy, center_x,center_y) + # OpenCV图像对象转换为字节流格式。 + _, buffer1 = cv2.imencode('.jpg',cropped_image1) + img_bytes1 = buffer1.tobytes() + # 文件名称 + unique_id1 = str(uuid.uuid4()) + imgNameOne = 'python/' + unique_id1 + "对比图违建放大图.jpg" + # 将图片上传到阿里云OSS + maxImages = upload_image_to_oss(imgNameOne, img_bytes1) + # 从URL加载图像 + resp1 = requests.get(mateSourceImgUrl) + # 创建临时文件 + temp_file1 = tempfile.NamedTemporaryFile(delete=False) + temp_file1.write(resp1.content) + temp_file1.close() + # 模板图画框 + img_array2 = np.frombuffer(resp1.content, np.uint8) + # 将矩形框绘制到图片上 + img_copy2 = cv2.imdecode(img_array2, cv2.IMREAD_COLOR) + # 在图像上绘制矩形框 + cv2.rectangle(img_copy2, (lef_x, lef_y), (right_x, right_y), (255, 255, 0), 10) + # OpenCV图像对象转换为字节流格式。 + _, buffer2 = cv2.imencode('.jpg', img_copy2) + img_bytes2 = buffer2.tobytes() + # 文件名称 + unique_id3 = str(uuid.uuid4()) + imgName3 = 'python/' + unique_id3 + "违建图.jpg" + # 将图片上传到阿里云OSS + url3 = upload_image_to_oss(imgName3, img_bytes2) + cropped_image2 = crop_image(img_copy2,center_x,center_y) # OpenCV图像对象转换为字节流格式。 + _, buffer1 = cv2.imencode('.jpg',cropped_image2) + img_bytes2 = buffer1.tobytes() + # 文件名称 + unique_id2 = str(uuid.uuid4()) + imgNameTwo = 'python/' + unique_id2 + "放大模板图.jpg" + # 将图片上传到阿里云OSS + maxMateSourceImgUrl = upload_image_to_oss(imgNameTwo, img_bytes2) + + id = re["id"] + taskId = re["taskId"] + map = {"lng": long, "lat": lat, "url": url, "taskImageId": id, "taskId": taskId, "images": url, + "handleType": 1,"areaL":w,"areaW":h,"area":area,"maxMateSourceImgUrl":maxMateSourceImgUrl, + "maxImages":maxImages,"mateSourceImgUrl":url3} + maplist.append(map) + + return maplist +# 根据像素坐标生成图片和经纬度,放入集合中,返回到前端 +def result(re,imgeurl,coordinateList): + if len(coordinateList)!=0: + print("读取") + # 从URL加载图像 + imgeurl=str(imgeurl).replace("https", "http") + resp = requests.get(imgeurl,stream=True) + # 创建临时文件 + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + for chunk in resp.iter_content(chunk_size=1024): + temp_file.write(chunk) + print("创建") + # 创建pyexiv2.Image对象 + # 从临时文件读取图像数据 + image = cv2.imread(temp_file.name) + if image is not None: + # 文件名称 + unique_id = str(uuid.uuid4()) + print("生成") + #前端缩放了,比例是:scale=4 + for item in coordinateList: + print(type(item)) + lef_x=item["lef_x"] + lef_y=item["lef_y"] + right_x = item["right_x"] + right_y = item["right_y"] + + #将比例还原 + scale=4 + lef_x=lef_x*scale + lef_y=lef_y*scale + right_x=right_x*scale + right_y=right_y*scale + + + # # 中心坐标 + # # 计算矩形框的中心点坐标 + # center_x = int(lef_x+right_x / 2) + # center_y = int(lef_y+right_y / 2) + # # # 经纬度转换 + # # long,lat=longandlat(image,center_x,center_y) + # # 将矩形框绘制到图片上 + # nparr = np.frombuffer(resp.content, np.uint8) + # img_copy = cv2.imdecode(nparr, cv2.IMREAD_COLOR) + # 在图像上绘制矩形框 + cv2.rectangle(image, (int(lef_x),int(lef_y)), (int(right_x),int(right_y)), (0,0,255), 10) + # OpenCV图像对象转换为字节流格式。 + _, buffer = cv2.imencode('.jpg', image) + img_bytes = buffer.tobytes() + imgName = 'python/' + unique_id + "违建图.jpg" + print("上传") + # 将图片上传到阿里云OSS + url = upload_image_to_oss(imgName, img_bytes) + id = re["id"] + taskId = re["taskId"] + map = {"id": id, "taskId": taskId,"discernImgUrl": url} + os.remove(temp_file.name) + return map +def messageData(msg): + topic = msg.topic + print("处理消息,时间:" + str(datetime.datetime.now())) + data = json.loads(msg.payload.decode()) + # 获取图片路径、图片名称和MQTT消息的时间戳 + if data: + if topic==appTwo: + print("通知") + if "id" in data: + print("数据情况",data) + id=data["id"] + notice = {"id":id } + on_publish(pushNoticeTopic, json.dumps(notice), 0) + if topic==weijian: + print("画违建矩形框") + if "sourceImgUrl" in data and "pixelCoordinate" in data: + image = data["sourceImgUrl"] + pixelCoordinate = data["pixelCoordinate"] + # 指向算法比对,获取图片 + coordinateList = json.loads(pixelCoordinate) + print(type(coordinateList)) + map = result(data, image, coordinateList) + if map is None: + print("生成图片出错,为null") + else: + url = "http://106.13.50.125:9006/ploughe-boot/wayline/waylineTaskImage/leakEdit" + # url = "http://192.168.1.20:9005/ploughe-boot/wayline/waylineTaskImage/leakEdit" + # 调取接口 + response = requests.post(url, json=map) + message = response.text + print("接口返回值:", message) + print("结束时间:" + str(datetime.datetime.now())) + elif topic==longandlat_mqtt: + print("提交违建,生产预警") + # 创建线程池 + with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: + if data and "waylineTaskImages" in data: + waylineImgList = data["waylineTaskImages"] + # 提交任务给线程池 + futurelist = [executor.submit(compute, re) for re in waylineImgList] + # 等待所有任务完成 + concurrent.futures.wait(futurelist) + # 获取每个任务的处理结果 + final_results = [item for sublist in + [future.result() for future in futurelist if future.result() is not None] for item + in + sublist] + print("返回的结果", final_results) + print("返回的结果数量", len(final_results)) + if len(final_results) != 0: + data['waylineTaskHandles'] = final_results + print("提交数据:", data) + url = "http://106.13.50.125:9006/ploughe-boot/wayline/waylineTaskWhee/leakEdit" + # url = "http://192.168.1.20:9005/ploughe-boot/wayline/waylineTaskWhee/leakEdit" + # 调取接口 + # 将list作为JSON数据 + # 发送POST请求,并将data作为请求体 + response = requests.post(url, json=data, headers={'Content-Type': 'application/json'}) + # 获取响应结果 + body = response.json() + print("接口返回值:", body) + print("结束时间:" + str(datetime.datetime.now())) + # 关闭线程池 + executor.shutdown() + + +def on_message(client, userdata, msg): + # """一旦订阅到消息, 回调此方法""" + print("主题:" + msg.topic + " 消息:" + msg.payload.decode('utf-8')) # 客户端返回的消息,使用gb2312编码中文不会报错 + # 多线程执行 + threading.Thread(target=messageData, args=((msg,))).start() + + +def signal_handler(signal, frame): + print('接收到键盘中断信号,程序将退出') + sys.exit(0) +def on_publish(topic, payload, qos): + re=client.publish(topic, payload, qos) + print("结果:"+str(re)+"时间:"+str(datetime.datetime.now())) + +def run(): + # 创建客户端对象 + + client.username_pw_set("adminRQ", "yongqiang666") + # 设置连接回调函数 + client.on_connect = on_connect + # 设置接收消息回调函数 + client.on_message = on_message + # 连接到MQTT代理 + client.connect("106.13.50.125", 1883, 60) + # 注册信号处理程序 + signal.signal(signal.SIGINT, signal_handler) + # 保持连接并接收消息 + client.loop_forever() + +if __name__ == '__main__': + run() + diff --git a/internalNet/internalNet.py b/internalNet/internalNet.py new file mode 100644 index 0000000..b77de70 --- /dev/null +++ b/internalNet/internalNet.py @@ -0,0 +1,170 @@ +import datetime + +import threading + + +import paho.mqtt.client as mqtt + +from requests_toolbelt.adapters.source import SourceAddressAdapter +import json + +import requests +import io +# 客户端id +client_id='python_mqqt_syncdevice111' + + + + + +# 连接回调函数 +def on_connect(client, userdata, flags, rc): + """一旦连接成功, 回调此方法""" + rc_status = ["连接成功", "协议版本错误", "无效的客户端标识", "服务器无法使用", "用户名或密码错误", "无授权"] + print("connect:", rc_status[rc]) + topics = ["syncdevice", "syncvirtualdevice", "device"] + # 要订阅的主题列表 + for topic in topics: + # 订阅主题 + print("订阅主题:",topic) + client.subscribe(topic) + + +def messageData(msg): + topic=msg.topic + print("处理消息,时间:" + str(datetime.datetime.now())) + data = json.loads(msg.payload.decode()) + print("数据",data) + try: + if data: + s = requests.Session() + # 指定特定网卡的IP地址'192.168.121.1',使用该网卡发送POST请求 + s.mount('http://', SourceAddressAdapter('192.168.8.143')) + map = { "tenantId": 81} + + if topic=="syncdevice": + deviceLogList=data["deviceLogList"] + print("数据对象==",deviceLogList) + for device in deviceLogList: + filePath=device["filePath"] + filePath = filePath.replace("\\", "/") + url="http://192.168.101.11:9000/detect/api/data/upload/remote" + fileUrl='http://106.13.50.125:9999/detect' + filePath + #本地测试ip + #res = requests.get('http://192.168.1.51:9099/detect' + filePath) + #file = io.BytesIO(res.content) + res = requests.get(fileUrl) + file = io.BytesIO(res.content) + files = {"file": file} + mapPath={"path":filePath} + response=s.post(url=url, data=mapPath,files=files) + message = response.text + + print("音频接口返回值:", message) + print("音频结束时间:" + str(datetime.datetime.now())) + if "userPhoto" in data: + userPhoto= data["userPhoto"] + if userPhoto: + for user in userPhoto: + filePath = user["url"] + filePath = filePath.replace("\\", "/") + url = "http://192.168.101.11:9000/detect/api/data/upload/remote" + res1 = requests.get('http://106.13.50.125:9999/detect' + filePath) + # 本地测试ip + #res = requests.get('http://192.168.1.51:9099/detect' + filePath) + file1 = io.BytesIO(res1.content) + files1={"file":file1} + mapPath = {"path": filePath} + response = s.post(url=url, data=mapPath, files=files1) + message = response.text + print("图片接口返回值:", message) + print("图片结束时间:" + str(datetime.datetime.now())) + #将数据上传到内网 + url = "http://192.168.101.11:9000/detect/admin/inspect/task_user/synchrodata" + response = s.post(url=url, json=data,headers={'Content-Type':'application/json'}) + message = response.text + print("同步数据接口返回值:", message) + print("同步数据结束时间:" + str(datetime.datetime.now())) + map["type"] = 2 + map["annotation"] = message + elif topic=="syncvirtualdevice": + # 将数据上传到内网 + url = "http://192.168.101.11:9000/detect/admin/iot/device/snycdevice/receive" + response = s.post(url=url, json=data, headers={'Content-Type': 'application/json'}) + message = response.text + print("同步设备数据接口返回值:", message) + map["type"] = 3 + map["annotation"] = message + elif topic=="device": + deviceLogDTOS = data["deviceLogDTOS"] + print("数据对象==", deviceLogDTOS) + for device in deviceLogDTOS: + filePath = device["filePath"] + filePath = filePath.replace("\\", "/") + url = "http://192.168.101.11:9000/detect/api/data/upload/remote" + fileUrl = 'http://106.13.50.125:9999/detect' + filePath + # res = requests.get('http://106.13.50.125:9999/detect' + filePath) + # 本地测试ip + # fileUrl='http://192.168.1.10:9099/detect' + filePath + print("地址路径" + fileUrl) + res = requests.get(fileUrl) + file = io.BytesIO(res.content) + mapPath = {"path": filePath} + files = {"file": file} + response = s.post(url=url, data=mapPath, files=files) + message = response.text + print("音频接口返回值:", message) + print("音频结束时间:" + str(datetime.datetime.now())) + # 将数据上传到内网 + url = "http://192.168.101.11:9000/detect/admin/iot/device_log/send/warningTwo" + response = s.post(url=url, json=data, headers={'Content-Type': 'application/json'}) + message = response.text + print("数据接口返回值:", message) + print("数据结束时间:" + str(datetime.datetime.now())) + map["type"] = 1 + map["annotation"] = message + waiurl = "http://106.13.50.125:9099/detect/admin/iot/internalLog/save" + print("日志数据",map) + result = requests.post(waiurl, json=map, headers={'Content-Type': 'application/json'}) + print("日志接口返回值:", result.text) + + except requests.exceptions.ConnectTimeout as e: + # 处理连接超时异常 + print("连接超时:", e) + run() + + except Exception as e: + # 处理其他异常 + print("发生异常:", e) + run() +def on_message(client, userdata, msg): + """一旦订阅到消息, 回调此方法""" + print("主题:" + msg.topic + " 消息:" + str(msg.payload.decode('utf-8'))) # 客户端返回的消息,使用gb2312编码中文不会报错 + # 将收到的消息转换为JSON格式 + threading.Thread(target=messageData, args=((msg,))).start() + + + + + +def run(): + # 创建客户端对象 + client = mqtt.Client(client_id=client_id) + client.username_pw_set("adminRQ", "yongqiang666") + # 设置连接回调函数 + client.on_connect = on_connect + # 设置接收消息回调函数 + client.on_message = on_message + # 连接到MQTT代理 + client.connect("106.13.50.125", 1883, 60) + # 保持连接并接收消息 + client.loop_forever() + +if __name__ == '__main__': + run() + + + + + + diff --git a/pi.py b/pi.py new file mode 100644 index 0000000..7be74b3 --- /dev/null +++ b/pi.py @@ -0,0 +1,16 @@ +import os + +folder_path = "C:/Users/yq183/Desktop/img" # 文件夹路径 +new_name_prefix = "img_" # 新名称前缀 + +# 获取文件夹下所有图片文件名 +image_files = [f for f in os.listdir(folder_path) if f.endswith(".jpg") or f.endswith(".png")or f.endswith(".jpeg")] + +# 遍历所有图片文件,进行重命名 +for i, image_file in enumerate(image_files): + old_path = os.path.join(folder_path, image_file) + new_name = f"{new_name_prefix}{i+1}.jpg" # 新名称格式 + new_path = os.path.join(folder_path, new_name) + os.rename(old_path, new_path) + +print("All images have been renamed successfully!")