From e13815e4d7c5bb6633004f6c2ea646bc49a719ec Mon Sep 17 00:00:00 2001 From: CaoWangrenbo Date: Mon, 27 Oct 2025 15:37:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=9C=AA=E6=AD=A3=E7=A1=AE=E5=86=99=E5=85=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cam_web.py | 159 +++++++++++++++++++------------------ templates/list_images.html | 78 +++++++++++------- 2 files changed, 130 insertions(+), 107 deletions(-) diff --git a/cam_web.py b/cam_web.py index 14623e8..da6f2d8 100644 --- a/cam_web.py +++ b/cam_web.py @@ -42,6 +42,7 @@ def init_db(): conn = sqlite3.connect(DATABASE_PATH) cursor = conn.cursor() # 创建表,存储图片信息,添加标注图片字段 + # --- Updated CREATE TABLE statement --- cursor.execute(''' CREATE TABLE IF NOT EXISTS images ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -52,9 +53,16 @@ def init_db(): timestamp REAL NOT NULL, metadata TEXT, comment TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + manual_detections_left TEXT, + manual_detections_right TEXT, + is_manual_labeled_left INTEGER DEFAULT 0, + is_manual_labeled_right INTEGER DEFAULT 0, + left_position INTEGER DEFAULT 0, -- Added column + right_position INTEGER DEFAULT 0 -- Added column ) ''') + # --- End Update --- conn.commit() conn.close() logger.info(f"Database {DATABASE_PATH} initialized.") @@ -142,53 +150,45 @@ def get_images_api(): conn = sqlite3.connect(DATABASE_PATH) cursor = conn.cursor() # 按时间倒序排列,包含标注图片字段和人工标注字段 - try: - cursor.execute(""" - SELECT id, left_filename, right_filename, left_marked_filename, right_marked_filename, - timestamp, metadata, comment, created_at, manual_detections, is_manual_labeled, - left_position, right_position - FROM images - ORDER BY timestamp DESC - """) - except sqlite3.OperationalError: - # 如果字段不存在,使用基本查询 - try: - cursor.execute(""" - SELECT id, left_filename, right_filename, left_marked_filename, right_marked_filename, - timestamp, metadata, comment, created_at, manual_detections, is_manual_labeled, - 0 as left_position, 0 as right_position - FROM images - ORDER BY timestamp DESC - """) - except sqlite3.OperationalError: - cursor.execute(""" - SELECT id, left_filename, right_filename, left_marked_filename, right_marked_filename, - timestamp, metadata, comment, created_at, NULL as manual_detections, 0 as is_manual_labeled, - 0 as left_position, 0 as right_position - FROM images - ORDER BY timestamp DESC - """) + # --- Updated query to directly select the new columns --- + # No more try/except needed for these specific columns if init_db creates them + cursor.execute(""" + SELECT id, left_filename, right_filename, left_marked_filename, right_marked_filename, + timestamp, metadata, comment, created_at, manual_detections_left, manual_detections_right, + is_manual_labeled_left, is_manual_labeled_right, + left_position, right_position + FROM images + ORDER BY timestamp DESC + """) + # --- End Update --- rows = cursor.fetchall() conn.close() + # print(rows) images = [] for row in rows: + # Note: Adjusting indices based on the new SELECT order images.append({ "id": row[0], "left_filename": row[1], "right_filename": row[2], - "left_marked_filename": row[3] or "", # 如果没有标注图片则显示空字符串 - "right_marked_filename": row[4] or "", # 如果没有标注图片则显示空字符串 + "left_marked_filename": row[3] or "", + "right_marked_filename": row[4] or "", "timestamp": row[5], "metadata": row[6], - "comment": row[7] or "", # 如果没有 comment 则显示空字符串 + "comment": row[7] or "", "created_at": row[8], - "manual_detections": row[9] or "[]", # 人工标注检测框结果 - "is_manual_labeled": bool(row[10]) if row[10] is not None else False, # 是否已完成人工标注 - "left_position": row[11] if row[11] is not None else 0, # 左侧位置编号 - "right_position": row[12] if row[12] is not None else 0 # 右侧位置编号 + "manual_detections_left": row[9] or "[]", # Renamed for clarity + "manual_detections_right": row[10] or "[]", # Renamed for clarity + "is_manual_labeled_left": bool(row[11]) if row[11] is not None else False, # Renamed for clarity + "is_manual_labeled_right": bool(row[12]) if row[12] is not None else False, # Renamed for clarity + "left_position": row[13], # Updated index + "right_position": row[14] # Updated index }) + + # print(images) + return jsonify(images) @app.route('/api/images', methods=['DELETE']) @@ -462,23 +462,26 @@ def update_image_position(): if not image_id: return jsonify({"error": "Image ID is required"}), 400 + logger.info(f"Updating position for image {image_id}: {left_position}, {right_position}") + conn = sqlite3.connect(DATABASE_PATH) cursor = conn.cursor() - - # 添加位置字段(如果不存在) - try: - cursor.execute(""" - ALTER TABLE images ADD COLUMN left_position INTEGER DEFAULT 0 - """) - except sqlite3.OperationalError: - pass - - try: - cursor.execute(""" - ALTER TABLE images ADD COLUMN right_position INTEGER DEFAULT 0 - """) - except sqlite3.OperationalError: - pass + + # --- Removed ALTER TABLE logic as columns are now in init_db --- + # try: + # cursor.execute(""" + # ALTER TABLE images ADD COLUMN left_position INTEGER DEFAULT 0 + # """) + # except sqlite3.OperationalError: + # pass + # + # try: + # cursor.execute(""" + # ALTER TABLE images ADD COLUMN right_position INTEGER DEFAULT 0 + # """) + # except sqlite3.OperationalError: + # pass + # --- End Removal --- # 更新位置字段 cursor.execute("UPDATE images SET left_position = ?, right_position = ? WHERE id = ?", @@ -545,34 +548,35 @@ def update_manual_detections(): conn.close() return jsonify({"error": "Image not found"}), 404 - # 添加人工标注字段(如果不存在) - try: - cursor.execute(""" - ALTER TABLE images ADD COLUMN manual_detections_left TEXT - """) - except sqlite3.OperationalError: - pass - - try: - cursor.execute(""" - ALTER TABLE images ADD COLUMN manual_detections_right TEXT - """) - except sqlite3.OperationalError: - pass - - try: - cursor.execute(""" - ALTER TABLE images ADD COLUMN is_manual_labeled_left INTEGER DEFAULT 0 - """) - except sqlite3.OperationalError: - pass - - try: - cursor.execute(""" - ALTER TABLE images ADD COLUMN is_manual_labeled_right INTEGER DEFAULT 0 - """) - except sqlite3.OperationalError: - pass + # --- Removed ALTER TABLE logic as columns are now in init_db --- + # try: + # cursor.execute(""" + # ALTER TABLE images ADD COLUMN manual_detections_left TEXT + # """) + # except sqlite3.OperationalError: + # pass + # + # try: + # cursor.execute(""" + # ALTER TABLE images ADD COLUMN manual_detections_right TEXT + # """) + # except sqlite3.OperationalError: + # pass + # + # try: + # cursor.execute(""" + # ALTER TABLE images ADD COLUMN is_manual_labeled_left INTEGER DEFAULT 0 + # """) + # except sqlite3.OperationalError: + # pass + # + # try: + # cursor.execute(""" + # ALTER TABLE images ADD COLUMN is_manual_labeled_right INTEGER DEFAULT 0 + # """) + # except sqlite3.OperationalError: + # pass + # --- End Removal --- # 根据 side 参数更新对应的人工标注结果 if side == 'left': @@ -667,7 +671,6 @@ def capture_button(data): logger.error(f"Error sending request: {e}") - if __name__ == '__main__': logger.info(f"Starting Flask-SocketIO server on {FLASK_HOST}:{FLASK_PORT}") socketio.run(app, host=FLASK_HOST, port=FLASK_PORT, debug=False, allow_unsafe_werkzeug=True) \ No newline at end of file diff --git a/templates/list_images.html b/templates/list_images.html index fca9c68..ae3021c 100644 --- a/templates/list_images.html +++ b/templates/list_images.html @@ -5,7 +5,7 @@ Saved Images - + @@ -187,37 +196,18 @@ // Actions const actionsCell = row.insertCell(6); + + console.log(image); + actionsCell.innerHTML = ` - - - - + + + + - + - + `; }); } @@ -240,6 +230,36 @@ } } + async function updatePosition(id) { + const leftInput = document.getElementById(`left-position-${id}`); + const rightInput = document.getElementById(`right-position-${id}`); + const leftValue = parseInt(leftInput.value) || 0; + const rightValue = parseInt(rightInput.value) || 0; + + console.log(`Updating position for image ID ${id}: Left=${leftValue}, Right=${rightValue}`); + if (leftValue < 0 || leftValue > 14 || rightValue < 0 || rightValue > 14) { + alert("Position values must be between 0 and 14."); + loadImages(); // Reload to reset invalid values + return; + } + + try { + const response = await fetch('/api/images/position', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ id: id, left_position: leftValue, right_position: rightValue }) + }); + if (!response.ok) { + const errorData = await response.json().catch(() => ({ error: response.statusText })); + throw new Error(errorData.error || `HTTP error! status: ${response.status}`); + } + document.getElementById('status').textContent = `Position for image ID ${id} updated.`; + } catch (error) { + console.error('Error updating position:', error); + document.getElementById('status').textContent = 'Error updating position: ' + error.message; + } + } + async function deleteImage(id) { if (!confirm(`Are you sure you want to delete image ID ${id}?`)) return;