新增侦查员和指挥员沟通,新增拍照功能 #4

Merged
pa2ltb7y5 merged 2 commits from zyp into main 4 weeks ago

@ -19,18 +19,31 @@ from car import CAR
#from PiCamera_H264_Server import stream
import threading
import cv2
import requests
app = Flask(__name__, static_url_path='')
# 照片保存路径
PHOTO_PATH = "photo.jpg"
picam2 = None
# picam2 = Picamera2()
# picam2.configure(picam2.create_video_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
# picam2.start()
def gen_frames(): # generate frame by frame from camera
def cameraon():
global picam2
picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
picam2.start()
def cameradown():
global picam2
picam2.stop()
picam2.close()
def gen_frames(): # generate frame by frame from camera
global picam2
cameraon()
while True:
# Capture frame-by-frame
frame = picam2.capture_array() # read the camera frame
@ -42,39 +55,79 @@ def gen_frames(): # generate frame by frame from camera
def capture_frame():
picam2.close()
frame = picam2.capture_array() # 假设picam2是你的相机对象
ret, buffer = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), 50])
img_str = base64.b64encode(buffer).decode()
picam2.start()
return img_str
# def capture_frame():
# picam2.close()
# frame = picam2.capture_array() # 假设picam2是你的相机对象
# ret, buffer = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), 50])
# img_str = base64.b64encode(buffer).decode()
# picam2.start()
# return img_str
# @app.route('/capture_frame')
# def capture_frame_route():
# img_str = capture_frame()
# return jsonify(img_str)
@app.route('/control/sendit', methods=['POST'])
def send_command():
# 定义目标 IP 地址、端口和路由
ip = "192.168.98.204"
port = 3000
route = "sendit2"
# 从请求中获取消息内容
data = request.json
message = data.get('message')
if message is None:
return jsonify({"error": "缺少 message 参数"}), 400
# 构建完整的 URL
url = f"http://{ip}:{port}/{route}"
# 发送 POST 请求
try:
response = requests.post(url, json={'message': message})
response.raise_for_status() # 检查请求是否成功
return f"命令已发送,服务器响应: {response.text}"
except requests.exceptions.RequestException as e:
return f"请求失败: {str(e)}", 500
@app.route('/capture')
def capture_image():
global picam2
# 获取一帧
frame = picam2.capture_array() # 读取当前帧
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 定义保存图片的路径
photo_path = "captured_photo.jpg"
@app.route('/capture_frame')
def capture_frame_route():
img_str = capture_frame()
return jsonify(img_str)
# 将帧保存为图片
try:
cv2.imwrite(photo_path, frame)
return f"Photo saved at {photo_path}"
except Exception as e:
return f"Failed to save photo: {str(e)}"
@app.route('/')
def index():
return render_template('index-t.html')
@app.route('/video_feed')
def video_feed():
#Video streaming route. Put this in the src attribute of an img tag
# @app.route('/video_feed')
# def video_feed():
# #Video streaming route. Put this in the src attribute of an img tag
# return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/startvadio')
def startvadio():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
#---------------------------------------------------------------------------------
@app.route('/take_photo')
def take_photo():
picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
picam2.start()
frame = picam2.capture_array() # Capture a single frame
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cv2.imwrite(PHOTO_PATH, frame) # Save the frame as a JPEG file
return send_file(PHOTO_PATH, as_attachment=True) # Send the file to download
#---------------------------------------------------------------------------------------
@app.route('/stopvadio')
def stopvadio():
cameradown()
return "closed"
# def gen(camera):
# """Video streaming generator function."""

@ -25,9 +25,11 @@
</head>
<body>
<h5>实时视频流</h5>
<img src="{{ url_for('video_feed') }}">
<button id="captureButton">Capture Frame</button>
<img id="frameImage" src="" alt="Captured Frame" style="display:none; width: 640px; height: 480px;">
<img src="{{ url_for('startvadio') }}">
<button type="button" onclick="capture()" >拍照</button>
<button type="button" onclick="startvadio()" >开始视频</button>
<button type="button" onclick="stopvadio()" >停止视频</button>
<!-- <img id="frameImage" src="" alt="Captured Frame" style="display:none; width: 640px; height: 480px;"> -->
<p> 小车控制界面</p>
<bodylink = "red">
<a href="control" target="_blank">小车控制</a>
@ -44,9 +46,7 @@
<button type="button" onclick="left()" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-left" > </button>
<button type="button" onclick="stop()" class="btn btn-lg btn-primary glyphicon glyphicon-stop"> </button>
<button type="button" onclick="right()" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-right" > </button>
<!-- ---------------------------------------- -->
<button type="button" onclick="takePhoto()">拍照</button>
<!-- ---------------------------------------- -->
</div>
<button id="rear" type="button" onclick="back()" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-down" style="margin-left: 56px;"> </button>
</div>
@ -67,6 +67,12 @@
</div>
<button id="down" type="button" onclick="down()" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-down" style="margin-left: 56px;"> </button>
</div>
<div>
<form id="sendCommandForm">
回复指令: <textarea id="message"></textarea><br>
<button type="button" onclick="sendCommand()">发送指令</button>
</form>
</div>
</div>
<script src='/Decoder.js'></script>
@ -91,6 +97,7 @@
ws.onclose = function (e) {
console.log('Client disconnected')
}
</script>
@ -98,31 +105,106 @@
<script>
$(document).ready(function() {
$('#captureButton').click(function() {
$.ajax({
url: '/capture_frame', // 后端路由地址
type: 'GET',
success: function(response) {
// 将响应中的图像数据设置到img标签的src属性
$('#frameImage').attr('src', 'data:image/jpeg;base64,' + response);
// 显示图像
$('#frameImage').show();
},
error: function(error) {
console.log('Error:', error);
function sendCommand() {
var message = document.getElementById('message').value;
$.ajax({
type: "POST",
url: "/control/sendit",
data: JSON.stringify({
message: message
}),
contentType: "application/json",
success: function (result) {
console.log(result);
alert("指令发送成功!");
},
error: function (error) {
console.log('Error:', error);
}
});
}
function capture() {
console.log("132465789891651354684");
$.ajax({
type: "GET",
dataType: "json",
url: "capture" ,
data: $('#form1').serialize(), //提交的数据
success: function (result) {
console.log(result); //打印服务端返回的数据(调试用)
if (result.resultCode == 200) {
}
});
;
},
error : function() {
}
});
});
}
function startvadio() {
// console.log("132465789891651354684");
$.ajax({
type: "GET",
dataType: "json",
url: "startvadio" ,
data: $('#form1').serialize(), //提交的数据
success: function (result) {
console.log(result); //打印服务端返回的数据(调试用)
if (result.resultCode == 200) {
}
;
},
error : function() {
}
});
}
function stopvadio() {
// console.log("132465789891651354684");
$.ajax({
type: "GET",
dataType: "json",
url: "stopvadio" ,
data: $('#form1').serialize(), //提交的数据
success: function (result) {
console.log(result); //打印服务端返回的数据(调试用)
if (result.resultCode == 200) {
}
;
},
error : function() {
}
});
}
// $(document).ready(function() {
// $('#captureButton').click(function() {
// $.ajax({
// url: '/capture_frame', // 后端路由地址
// type: 'GET',
// success: function(response) {
// // 将响应中的图像数据设置到img标签的src属性
// $('#frameImage').attr('src', 'data:image/jpeg;base64,' + response);
// // 显示图像
// $('#frameImage').show();
// },
// error: function(error) {
// console.log('Error:', error);
// }
// });
// });
// });
function printClicked() {
// console.log("132465789891651354684");
}
// ---------------------------------------
function takePhoto() {
window.location.href = "{{ url_for('take_photo') }}"; // 重定向到拍照请求
}
// ---------------------------------------
function forward() {
console.log("132465789891651354684");
$.ajax({

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 KiB

Loading…
Cancel
Save