为了创建一个具有科技质感且能动态展示结果的纸箱变形检测傅里叶变换网页,下面将分别更新 HTML、CSS 和 JavaScript 文件。以下是更新后的代码:
1. HTML 文件 (index.html
)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>纸箱变形检测 - 傅里叶变换</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-box-open"></i> 纸箱变形检测系统</h1>
<div class="status-bar">
<span class="status-item"><i class="fas fa-signal"></i> 系统就绪</span>
<span class="status-item"><i class="fas fa-battery-full"></i> 100%</span>
</div>
</div>
<div class="main-content">
<input type="file" id="imageInput" accept="image/*" class="file-input">
<label for="imageInput" class="file-input-label">
<i class="fas fa-upload"></i> 选择纸箱图片
</label>
<div class="progress-bar">
<div class="progress" id="progress"></div>
</div>
<div class="canvas-container">
<div class="canvas-wrapper">
<h3>原始图像</h3>
<canvas id="originalCanvas"></canvas>
</div>
<div class="canvas-wrapper">
<h3>傅里叶变换结果</h3>
<canvas id="transformedCanvas"></canvas>
</div>
</div>
<div class="analysis-result" id="analysisResult">
<h3>分析结果</h3>
<p>状态: <span id="status">未检测</span></p>
<p>变形程度: <span id="deformationLevel">无</span></p>
</div>
</div>
<div class="footer">
<p>© 2024 纸箱变形检测实验室. 保留所有权利.</p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
2. CSS 文件 (styles.css
)
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #1a1a1a;
color: #ffffff;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
width: 90%;
max-width: 1200px;
background-color: #2d2d2d;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
overflow: hidden;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background-color: #333333;
border-bottom: 1px solid #444444;
animation: slideDown 0.5s ease-out;
}
@keyframes slideDown {
from { transform: translateY(-100%); }
to { transform: translateY(0); }
}
.status-bar {
display: flex;
gap: 20px;
}
.status-item {
display: flex;
align-items: center;
gap: 5px;
font-size: 14px;
color: #00ffcc;
}
.main-content {
padding: 20px;
}
.file-input {
display: none;
}
.file-input-label {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: #ffffff;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.file-input-label:hover {
background-color: #0056b3;
}
.progress-bar {
width: 100%;
height: 20px;
background-color: #333333;
border-radius: 10px;
margin: 20px 0;
overflow: hidden;
}
.progress {
height: 100%;
background-color: #00ffcc;
width: 0%;
transition: width 0.3s ease;
}
.canvas-container {
display: flex;
gap: 20px;
margin-top: 20px;
}
.canvas-wrapper {
flex: 1;
background-color: #333333;
padding: 20px;
border-radius: 5px;
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from { transform: scale(0.9); }
to { transform: scale(1); }
}
canvas {
border: 2px solid #00ffcc;
border-radius: 5px;
width: 100%;
height: auto;
}
.analysis-result {
background-color: #333333;
padding: 20px;
border-radius: 5px;
margin-top: 20px;
animation: fadeIn 0.5s ease-out;
}
.footer {
padding: 10px;
text-align: center;
background-color: #333333;
border-top: 1px solid #444444;
font-size: 12px;
color: #888888;
}
3. JavaScript 文件 (script.js
)
// 获取 DOM 元素
const imageInput = document.getElementById('imageInput');
const originalCanvas = document.getElementById('originalCanvas');
const transformedCanvas = document.getElementById('transformedCanvas');
const progressBar = document.getElementById('progress');
const statusSpan = document.getElementById('status');
const deformationLevelSpan = document.getElementById('deformationLevel');
const originalCtx = originalCanvas.getContext('2d');
const transformedCtx = transformedCanvas.getContext('2d');
// 为文件输入添加事件监听器
imageInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const img = new Image();
img.onload = function() {
// 绘制原始图像
originalCanvas.width = img.width;
originalCanvas.height = img.height;
originalCtx.drawImage(img, 0, 0);
// 模拟处理进度
let progress = 0;
const interval = setInterval(() => {
progress += 10;
progressBar.style.width = `${progress}%`;
if (progress >= 100) {
clearInterval(interval);
// 执行傅里叶变换
const imageData = originalCtx.getImageData(0, 0, img.width, img.height);
const transformedData = performFourierTransform(imageData);
// 绘制傅里叶变换结果
transformedCanvas.width = img.width;
transformedCanvas.height = img.height;
transformedCtx.putImageData(transformedData, 0, 0);
// 模拟分析结果
statusSpan.textContent = '检测完成';
deformationLevelSpan.textContent = '轻度变形';
}
}, 300);
};
img.src = event.target.result;
};
reader.readAsDataURL(file);
}
});
// 简化版傅里叶变换函数(示例)
function performFourierTransform(imageData) {
// 这里应该实现实际的傅里叶变换算法
// 为了简化,这里只是返回原始图像数据
return imageData;
}
说明
- HTML 文件:添加了 Font Awesome 图标库,增加了系统状态栏、进度条和分析结果展示区域,提升界面的科技感和交互性。
- CSS 文件:使用深色背景和亮色边框,营造科技感氛围。添加了多种动画效果,如淡入、下滑和缩放,让页面更加动态。
- JavaScript 文件:添加了进度条模拟处理过程,在处理完成后展示分析结果,增强了动态展示效果。实际应用中需要实现完整的傅里叶变换算法。
Python实现
script.js
// 获取 DOM 元素
const imageInput = document.getElementById('imageInput');
const originalCanvas = document.getElementById('originalCanvas');
const transformedCanvas = document.getElementById('transformedCanvas');
const progressBar = document.getElementById('progress');
const statusSpan = document.getElementById('status');
const deformationLevelSpan = document.getElementById('deformationLevel');
const originalCtx = originalCanvas.getContext('2d');
const transformedCtx = transformedCanvas.getContext('2d');
// 为文件输入添加事件监听器
imageInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const img = new Image();
img.onload = function() {
// 绘制原始图像
originalCanvas.width = img.width;
originalCanvas.height = img.height;
originalCtx.drawImage(img, 0, 0);
// 模拟处理进度
let progress = 0;
const interval = setInterval(() => {
progress += 10;
progressBar.style.width = `${progress}%`;
if (progress >= 100) {
clearInterval(interval);
// 发送图像到后端进行处理
const formData = new FormData();
formData.append('image', file);
fetch('/process', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// 绘制傅里叶变换结果
const transformedImage = new Image();
transformedImage.src = data.transformed_image;
transformedImage.onload = function() {
transformedCanvas.width = transformedImage.width;
transformedCanvas.height = transformedImage.height;
transformedCtx.drawImage(transformedImage, 0, 0);
}
// 更新分析结果
statusSpan.textContent = '检测完成';
deformationLevelSpan.textContent = data.deformation_level;
});
}
}, 300);
}
img.src = event.target.result;
}
reader.readAsDataURL(file);
}
});
styles.css
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #1a1a1a;
color: #ffffff;
margin: 0;
padding: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.status-bar {
display: flex;
gap: 20px;
}
.file-input {
display: none;
}
.file-input-label {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.file-input-label:hover {
background-color: #0056b3;
}
.progress-bar {
height: 20px;
background-color: #333333;
border-radius: 10px;
margin: 20px 0;
overflow: hidden;
}
.progress {
height: 100%;
background-color: #00ffcc;
width: 0%;
transition: width 0.3s ease;
}
.canvas-container {
display: flex;
gap: 20px;
margin-top: 20px;
}
.canvas-wrapper {
flex: 1;
}
canvas {
border: 2px solid #00ffcc;
box-shadow: 0 0 10px rgba(0, 255, 204, 0.3);
}
.analysis-result {
margin-top: 20px;
padding: 20px;
background-color: #333333;
border-radius: 5px;
}
.footer {
margin-top: 20px;
text-align: center;
color: #666;
}
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>纸箱变形检测 - 傅里叶变换</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-box-open"></i> 纸箱变形检测系统</h1>
<div class="status-bar">
<span class="status-item"><i class="fas fa-signal"></i> 系统就绪</span>
<span class="status-item"><i class="fas fa-battery-full"></i> 100%</span>
</div>
</div>
<div class="main-content">
<input type="file" id="imageInput" accept="image/*" class="file-input">
<label for="imageInput" class="file-input-label">
<i class="fas fa-upload"></i> 选择纸箱图片
</label>
<div class="progress-bar">
<div class="progress" id="progress"></div>
</div>
<div class="canvas-container">
<div class="canvas-wrapper">
<h3>原始图像</h3>
<canvas id="originalCanvas"></canvas>
</div>
<div class="canvas-wrapper">
<h3>傅里叶变换结果</h3>
<canvas id="transformedCanvas"></canvas>
</div>
</div>
<div class="analysis-result" id="analysisResult">
<h3>分析结果</h3>
<p>状态: <span id="status">未检测</span></p>
<p>变形程度: <span id="deformationLevel">无</span></p>
</div>
</div>
<div class="footer">
<p>© 2025 纸箱变形检测实验室. 保留所有权利.</p>
</div>
</div>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>
app.py
from flask import Flask, render_template, request, jsonify
from PIL import Image
import numpy as np
import base64
import io
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/process', methods=['POST'])
def process():
# 获取上传的图像
file = request.files['image']
img = Image.open(file.stream)
img = img.convert('L') # 转换为灰度图像
# 执行傅里叶变换
img_array = np.array(img)
fft_result = np.fft.fft2(img_array)
fft_shifted = np.fft.fftshift(fft_result)
magnitude_spectrum = 20*np.log(np.abs(fft_shifted))
# 归一化并转换为图像
magnitude_spectrum = (magnitude_spectrum - np.min(magnitude_spectrum)) / (np.max(magnitude_spectrum) - np.min(magnitude_spectrum)) * 255
magnitude_spectrum = magnitude_spectrum.astype(np.uint8)
transformed_img = Image.fromarray(magnitude_spectrum)
# 模拟变形程度检测
deformation_level = '轻度变形'
# 将处理后的图像转换为 base64 编码
buffer = io.BytesIO()
transformed_img.save(buffer, format='PNG')
transformed_img_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
return jsonify({
'transformed_image': 'data:image/png;base64,' + transformed_img_base64,
'deformation_level': deformation_level
})
if __name__ == '__main__':
app.run(debug=True)