commit de19155021bd383cb9d66bc4635cd3f00b7b2829
Author: Tyrion <1216776075@qq.com>
Date: Fri Jul 22 11:26:34 2022 +0800
Initial commit
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/djangoProject.iml b/.idea/djangoProject.iml
new file mode 100644
index 0000000..4b6174d
--- /dev/null
+++ b/.idea/djangoProject.iml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
new file mode 100644
index 0000000..20eefa1
--- /dev/null
+++ b/.idea/jsLibraryMappings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..6a48157
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..5abfc21
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/db.sqlite3 b/db.sqlite3
new file mode 100644
index 0000000..e69de29
diff --git a/djangoProject/__init__.py b/djangoProject/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/djangoProject/asgi.py b/djangoProject/asgi.py
new file mode 100644
index 0000000..a02c55c
--- /dev/null
+++ b/djangoProject/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for djangoProject project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')
+
+application = get_asgi_application()
diff --git a/djangoProject/settings.py b/djangoProject/settings.py
new file mode 100644
index 0000000..c688a85
--- /dev/null
+++ b/djangoProject/settings.py
@@ -0,0 +1,129 @@
+"""
+Django settings for djangoProject project.
+
+Generated by 'django-admin startproject' using Django 4.0.6.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/4.0/ref/settings/
+"""
+import os
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'django-insecure-ya9!!nl84l$a#)ez8np*9k4=y0vq8qv+dm)f+pub3x48^e7am&'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'djangoProject.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [BASE_DIR / 'templates']
+ ,
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'djangoProject.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/4.0/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/4.0/howto/static-files/
+
+STATIC_URL = 'static/'
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+STATICFILES_DIRS = [
+ os.path.join(BASE_DIR, 'static'),
+]
+MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
diff --git a/djangoProject/urls.py b/djangoProject/urls.py
new file mode 100644
index 0000000..c26b285
--- /dev/null
+++ b/djangoProject/urls.py
@@ -0,0 +1,52 @@
+"""djangoProject URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/4.0/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path
+from . import views
+
+urlpatterns = [
+ path('', views.to_img_load),
+ path('histogram/', views.histogram),
+ path('greyHistogram/', views.greyHistogram),
+ path('colorHistogram/', views.colorHistogram),
+ path('piecewiseLinearProcessing/', views.piecewiseLinearProcessing),
+ path('enlarge/', views.enlarge),
+ path('move/', views.move),
+ path('spin/', views.spin),
+ path('horizontalFlip/', views.horizontalFlip),
+ path('verticalFlip/', views.verticalFlip),
+ path('crossFlip/', views.crossFlip),
+ path('affineTransformation/', views.affineTransformation),
+ path('enhance/', views.enhance),
+ path('robs/', views.robs),
+ path('sob/', views.sob),
+ path('lap/', views.lap),
+ path('log/', views.log),
+ path('cny/', views.cny),
+ path('MeanFilter/', views.MeanFilter),
+ path('MedFilter/', views.MedFilter),
+ path('HoughLineChange/', views.HoughLineChange),
+ path('erode/', views.erode),
+ path('dialate/', views.dialate),
+ path('sp_noise/', views.sp_noise),
+ path('gasuss_noise/', views.gasuss_noise),
+ path('highPassFilter/', views.highPassFilter),
+ path('IdealLowPassFiltering/', views.IdealLowPassFiltering),
+ path('butterworth_low_filter/', views.butterworth_low_filter),
+ path('IdealHighPassFiltering/', views.IdealHighPassFiltering),
+ path('butterworth_high_filter/', views.butterworth_high_filter),
+ path('sharpen/', views.sharpen)
+]
diff --git a/djangoProject/views.py b/djangoProject/views.py
new file mode 100644
index 0000000..45fd66e
--- /dev/null
+++ b/djangoProject/views.py
@@ -0,0 +1,938 @@
+import base64
+import random
+from tkinter import Image
+import numpy as np
+import cv2
+import sys
+import cv2 as cv
+import matplotlib.pyplot as plt
+import numpy as np
+from PIL import Image
+from django.http import HttpResponse, JsonResponse
+from django.shortcuts import render
+from matplotlib import pyplot as plt
+
+
+from djangoProject import settings
+
+
+# 主页面
+def to_img_load(request):
+ return render(request, 'upload.html')
+
+
+# 绘制直方图
+def histogram(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ print(name)
+ path = settings.MEDIA_ROOT + '/' + image.name
+ with open(path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(path)
+ color = ('b', 'g', 'r')
+ for i, col in enumerate(color):
+ hist = cv2.calcHist([img], [i], None, [256], [0, 256])
+ plt.plot(hist, color=col)
+ plt.xlim([0, 256])
+ plt.savefig(path)
+ try:
+ data = {'state': 'static/media/'+name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 灰度直方图
+def greyHistogram(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + image.name
+ print(img_path)
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img_PIL = Image.open(img_path)
+ img = np.array(img_PIL)
+ img_gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
+ hist = cv.calcHist([img_gray], [0], None, [256], [0, 255])
+ plt.plot(hist)
+ plt.xlim([0, 255])
+ plt.savefig(img_path)
+ try:
+ data = {'state': 'static/media/'+name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 彩色直方图
+def colorHistogram(request):
+ if request.method == 'POST':
+ color = ["r", "g", "b"]
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + image.name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ b, g, r = cv2.split(img)
+ img = cv2.merge([r, g, b])
+ # 绘制彩色直方图,需要对每个通道进行遍历,并且找到最大值和最小值
+ for index, c in enumerate(color):
+ hist = cv2.calcHist([img], [index], None, [256], [0, 255])
+ plt.plot(hist, color=c)
+ plt.xlim([0, 255])
+ plt.savefig(img_path)
+ try:
+ data = {'state': 'static/media/'+name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 分段线性处理
+def piecewiseLinearProcessing(request):
+ # 定义图像数据的路径
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path, 0)
+ h, w = img.shape[:2]
+ out = np.zeros(img.shape, np.uint8)
+ for i in range(h):
+ for j in range(w):
+ pix = img[i][j]
+ if pix < 50:
+ out[i][j] = 0.5 * pix
+ elif pix < 150:
+ out[i][j] = 3.6 * pix - 310
+ else:
+ out[i][j] = 0.238 * pix + 194
+ out = np.around(out)
+ out = out.astype(np.uint8)
+ cv2.imwrite(img_path, out)
+ try:
+ data = {'state': 'static/media/'+name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 放大图像至原来的两倍,使用双线性插值法????
+def enlarge(request):
+ # 定义图像数据的路径
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ l, w, h = img.shape
+ img = cv2.resize(img, (0, 0), fx=2, fy=2, interpolation=cv2.INTER_LINEAR)
+ cv2.imwrite(img_path, img)
+ try:
+ data = {'state': 'static/media/'+name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 图片平移 构建移动矩阵,x轴左移 10 个像素,y轴下移 30 个
+def move(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ height, width, channel = img.shape
+ M = np.float32([[1, 0, 30], [0, 1, 60]])
+ img = cv2.warpAffine(img, M, (width, height))
+ cv2.imwrite(img_path, img)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 构建矩阵,旋转中心坐标为处理后图片长宽的一半,旋转角度为45度,缩放因子为1
+def spin(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ height, width, channel = img.shape
+ rows, cols, depth = img.shape
+ M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)
+ dst = cv2.warpAffine(img, M, (width, height))
+ cv2.imwrite(img_path, dst)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 水平翻转
+def horizontalFlip(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ horizontal = cv2.flip(img, 1, dst=None)
+ cv2.imwrite(img_path, horizontal)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 垂直翻转
+def verticalFlip(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ vertical = cv2.flip(img, 0, dst=None)
+ cv2.imwrite(img_path, vertical)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 对角线翻转
+def crossFlip(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ cross = cv2.flip(img, -1, dst=None)
+ cv2.imwrite(img_path, cross)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 仿射变换
+def affineTransformation(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ img = cv2.resize(img, (256, 256))
+ rows, cols = img.shape[: 2]
+ # 设置图像仿射变化矩阵
+ post1 = np.float32([[50, 50], [200, 50], [50, 200]])
+ post2 = np.float32([[10, 100], [200, 50], [100, 250]])
+ M = cv2.getAffineTransform(post1, post2)
+ # 图像仿射变换,及保存
+ result = cv2.warpAffine(img, M, (rows, cols))
+ cv2.imwrite(img_path, result)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 图片增强
+def enhance(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ # 1. 灰度模式读取图像,图像名为CRH
+ CRH = cv2.imread(img_path, 0)
+
+ # 2. 计算图像梯度。首先要对读取的图像进行数据变换,因为使用了
+ # numpy对梯度进行数值计算,所以要使用
+ # CRH.astype('float')进行数据格式变换。
+ row, col = CRH.shape
+ CRH_f = np.copy(CRH)
+ CRH_f = CRH_f.astype('float')
+ gradient = np.zeros((row, col))
+ for x in range(row - 1):
+ for y in range(col - 1):
+ gx = abs(CRH_f[x + 1, y] - CRH_f[x, y])
+ gy = abs(CRH_f[x, y + 1] - CRH_f[x, y])
+ gradient[x, y] = gx + gy
+ # 3. 对图像进行增强,增强后的图像变量名为sharp
+ sharp = CRH_f + gradient
+ sharp = np.where(sharp > 255, 255, sharp)
+ sharp = np.where(sharp < 0, 0, sharp)
+ # 数据类型变换
+ gradient = gradient.astype('uint8')
+ sharp = sharp.astype('uint8')
+ cv2.imwrite(img_path, sharp)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# robs算子图片增强
+def robs(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ # 1. 灰度化处理图像
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ # 2. Roberts算子
+ kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
+ kernely = np.array([[0, -1], [1, 0]], dtype=int)
+ # 3. 卷积操作
+ x = cv2.filter2D(gray, cv2.CV_16S, kernelx)
+ y = cv2.filter2D(gray, cv2.CV_16S, kernely)
+ # 4. 数据格式转换
+ absx = cv2.convertScaleAbs(x)
+ absy = cv2.convertScaleAbs(y)
+ Roberts = cv2.addWeighted(absx, 0.5, absy, 0.5, 0)
+ cv2.imwrite(img_path, Roberts)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 使用 Sobel 算子提取边缘
+def sob(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ # 1. 灰度化处理图像
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ # 2. 求Sobel 算子
+ sx = cv2.Sobel(gray, cv2.CV_16S, 1, 0)
+ sy = cv2.Sobel(gray, cv2.CV_16S, 0, 1)
+ # 3. 数据格式转换
+ absx = cv2.convertScaleAbs(sx)
+ absy = cv2.convertScaleAbs(sy)
+ # 4. 组合图像
+ Sobel = cv2.addWeighted(absx, 0.5, absy, 0.5, 0)
+ cv2.imwrite(img_path, Sobel)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 使用 Laplacian 算子提取边缘
+def lap(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ # 1. 灰度化处理图像
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ # 2. 高斯滤波
+ grayG = cv2.GaussianBlur(gray, (5, 5), 0)
+ fltI = cv2.Laplacian(grayG, cv2.CV_16S, ksize=3)
+ # 3. 拉普拉斯算法
+ Laplacian = cv2.convertScaleAbs(fltI)
+ cv2.imwrite(img_path, Laplacian)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 使用 LoG 算子提取边缘
+def log(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
+ gray = cv2.copyMakeBorder(gray, 2, 2, 2, 2, borderType=cv2.BORDER_REPLICATE)
+ image = cv2.GaussianBlur(gray, (3, 3), 0, 0)
+ m1 = np.array([[0, 0, -1, 0, 0],
+ [0, -1, -2, -1, 0],
+ [-1, -2, 16, -2, -1],
+ [0, -1, -2, -1, 0],
+ [0, 0, -1, 0, 0]])
+ row = image.shape[0]
+ col = image.shape[1]
+ image1 = np.zeros(image.shape)
+ for i in range(2, row - 2):
+ for j in range(2, col - 2):
+ image1[i, j] = np.sum(m1 * image[i - 2:i + 3, j - 2:j + 3, 1])
+ image1 = cv2.convertScaleAbs(image1)
+ cv2.imwrite(img_path, image1)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# Canny 边缘检测过程
+def cny(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ src = cv2.imread(img_path)
+ blur = cv2.GaussianBlur(src, (3, 3), 0)
+
+ gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
+
+ gradx = cv2.Sobel(gray, cv2.CV_16SC1, 1, 0)
+ grady = cv2.Sobel(gray, cv2.CV_16SC1, 0, 1)
+ edge_output = cv2.Canny(gradx, grady, 50, 150)
+ cv2.imwrite(img_path, edge_output)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 均值滤波器
+def MeanFilter(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ w = gray.shape[1]
+ h = gray.shape[0]
+ newing = np.array(gray)
+
+ lbing = np.zeros((h + 2, w + 2), np.float32)
+ tmping = np.zeros((h + 2, w + 2))
+ myh = h + 2
+ myw = w + 2
+ tmping[1:myh - 1, 1:myw - 1] = newing[0:h, 0:w]
+
+ a = 1 / 8.0
+ kernel = a * np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]])
+ for y in range(1, myh - 1):
+ for x in range(1, myw - 1):
+ lbing[y, x] = np.sum(kernel * tmping[y - 1:y + 2, x - 1:x + 2])
+
+ result = np.array(lbing[1:myh - 1, 1:myw - 1], np.uint8)
+ cv2.imwrite(img_path, result)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 中值滤波器
+def MedFilter(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ w = img.shape[1]
+ h = img.shape[0]
+ median = np.array(img)
+ for y in range(1, w):
+ for x in range(1, h):
+ median[x, y] = np.median(img[x - 1:x + 2, y - 1:y + 2])
+ cv2.imwrite(img_path, median)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# Hough线段变化
+def HoughLineChange(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ img = cv2.GaussianBlur(img, (3, 3), 0)
+ edges = cv2.Canny(img, 50, 150, apertureSize=3)
+ lines = cv2.HoughLines(edges, 1, np.pi/2, 118)
+
+ result = img.copy()
+ for i_line in lines:
+ for line in i_line:
+ rho = line[0]
+ theta = line[1]
+ if (theta < (np.pi / 4.)) or (theta > (3. * np.pi / 4.0)): # 垂直直线
+ pt1 = (int(rho / np.cos(theta)), 0)
+ pt2 = (int((rho - result.shape[0] * np.sin(theta)) / np.cos(theta)), result.shape[0])
+ cv2.line(result, pt1, pt2, (0, 0, 255))
+ else:
+ pt1 = (0, int(rho / np.sin(theta)))
+ pt2 = (result.shape[1], int((rho - result.shape[1] * np.cos(theta)) / np.sin(theta)))
+ cv2.line(result, pt1, pt2, (0, 0, 255), 1)
+
+
+ minLineLength = 200
+ maxLineGap = 15
+
+
+ linesP = cv2.HoughLinesP(edges, 1, np.pi/180, 80, minLineLength, maxLineGap)
+
+ result_P = img.copy()
+ for i_P in linesP:
+ for x1, y1, x2, y2 in i_P:
+ cv2.line(result_P, (x1, y1), (x2, y2), (0, 255, 0), 3)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()
+ cv2.imwrite(img_path, result_P)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 腐蚀
+def erode(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ src = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+ # 使用一个5x5的交叉型结构元(核心在几何中心)对二值图片src进行腐蚀
+ kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
+ erosion = cv2.erode(src, kernel)
+ cv2.imwrite(img_path, erosion)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 膨胀
+def dialate(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ src = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+ # 使用一个5x5的交叉型结构元(核心在几何中心)对二值图片src进行膨胀
+ kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
+ dilation = cv2.dilate(src, kernel)
+ cv2.imwrite(img_path, dilation)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 开操作######
+def openMorphing(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ retval, dst = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
+
+ # 定义十字形结构元素
+ kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(10,10))
+
+ im_op = cv2.morphologyEx(dst, cv2.MORPH_OPEN,kernel)
+ cv2.imwrite(img_path, im_op)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 闭操作
+def closeMorphing(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ retval, dst = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
+
+ # 定义十字形结构元素
+ kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (10, 10))
+
+ im_cl = cv2.morphologyEx(dst, cv2.MORPH_CLOSE, kernel)
+ cv2.imwrite(img_path, im_cl)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 雪花噪声
+def sp_noise(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ prob = 0.2
+ # 待输出的图片
+ output = np.zeros(img.shape, np.uint8)
+
+ # 遍历图像,获取叠加噪声后的图像
+ thres = 1 - prob
+ for i in range(img.shape[0]):
+ for j in range(img.shape[1]):
+ rdn = random.random()
+ if rdn < prob:
+ output[i][j] = 0
+ elif rdn > thres:
+ output[i][j] = 255
+ else:
+ output[i][j] = img[i][j]
+ cv2.imwrite(img_path, output)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 添加高斯噪声,mean : 均值 , var : 方差
+def gasuss_noise(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ image = np.array(img / 255, dtype=float)
+ var = 0.001
+ mean = 0
+ noise = np.random.normal(mean, var ** 0.5, image.shape)
+ out = image + noise
+ if out.min() < 0:
+ low_clip = -1.
+ else:
+ low_clip = 0.
+ out = np.clip(out, low_clip, 1.0)
+ out = np.uint8(out * 255)
+ cv2.imwrite(img_path, out)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# 高通滤波
+def highPassFilter(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ output = np.zeros(image.shape, np.uint8)
+
+ for i in range(image.shape[0]):
+ for j in range(image.shape[1]):
+ if 200 < image[i][j]:
+ output[i][j] = image[i][j]
+ else:
+ output[i][j] = 0
+ cv2.imwrite(img_path, output)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+##########
+##########
+# 空域锐化
+##########
+#########
+
+
+# Roberts因子锐化
+def Roberts(image):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
+ img_Roberts = np.zeros(img.shape, dtype=int)
+ for i in range(1, img.shape[0] - 1): # 第一列和最后一列不用处理
+ for j in range(1, img.shape[1] - 1):
+ img_Roberts[i][j] = abs((int)(img[i + 1][j + 1]) - (int)(img[i][j])) + abs(
+ (int)(img[i + 1][j]) - (int)(img[i][j + 1]))
+ result = np.array(img_Roberts)
+ plt.subplot(244), plt.title("4.Roberts锐化后"), plt.axis('off')
+ plt.imshow(img_Roberts, cmap="gray")
+ plt.show()
+
+
+def sharpen(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32) # 锐化
+ dst = cv2.filter2D(img, -1, kernel=kernel)
+ cv2.imwrite(img_path, dst)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+##########
+##########
+# 频域锐化
+##########
+#########
+
+# 理想低通滤波
+def IdealLowPassFiltering(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ f_shift = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ # 设置滤波半径
+ D0 = 80
+ # 初始化
+ m = f_shift.shape[0]
+ n = f_shift.shape[1]
+ h1 = np.zeros((m, n))
+ x0 = np.floor(m / 2)
+ y0 = np.floor(n / 2)
+ for i in range(m):
+ for j in range(n):
+ D = np.sqrt((i - x0) ** 2 + (j - y0) ** 2)
+ if D <= D0:
+ h1[i][j] = 1
+ result = np.multiply(f_shift, h1)
+ cv2.imwrite(img_path, result)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# Butterworth低通滤波器
+def butterworth_low_filter(request):
+ """
+ 生成一个Butterworth低通滤波器(并返回)
+ """
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ D0 = 20
+ rank = 2
+ h, w = img.shape[:2]
+ filter_img = np.zeros((h, w))
+ u = np.fix(h / 2)
+ v = np.fix(w / 2)
+ for i in range(h):
+ for j in range(w):
+ d = np.sqrt((i - u) ** 2 + (j - v) ** 2)
+ filter_img[i, j] = 1 / (1 + 0.414 * (d / D0) ** (2 * rank))
+ cv2.imwrite(img_path, filter_img)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+##########
+##########
+# 频域平滑
+##########
+#########
+
+
+# 理想高通滤波
+def IdealHighPassFiltering(request):
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ f_shift = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+ # 设置滤波半径
+ D0 = 80
+ # 初始化
+ m = f_shift.shape[0]
+ n = f_shift.shape[1]
+ h1 = np.zeros((m, n))
+ x0 = np.floor(m / 2)
+ y0 = np.floor(n / 2)
+ for i in range(m):
+ for j in range(n):
+ D = np.sqrt((i - x0) ** 2 + (j - y0) ** 2)
+ if D >= D0:
+ h1[i][j] = 1
+ result = np.multiply(f_shift, h1)
+ cv2.imwrite(img_path, result)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
+
+
+# Butterworth高通滤波器
+def butterworth_high_filter(request):
+ """
+ 生成一个Butterworth高通滤波器(并返回)
+ """
+ if request.method == 'POST':
+ image = request.FILES.get('picture')
+ name = image.name
+ img_path = settings.MEDIA_ROOT + '/' + name
+ with open(img_path, 'wb') as pic:
+ for c in image.chunks():
+ pic.write(c)
+ img = cv2.imread(img_path)
+ D0 = 40
+ rank = 2
+ h, w = img.shape[:2]
+ filter_img = np.zeros((h, w))
+ u = np.fix(h / 2)
+ v = np.fix(w / 2)
+ for i in range(h):
+ for j in range(w):
+ d = np.sqrt((i - u) ** 2 + (j - v) ** 2)
+ filter_img[i, j] = 1 / (1 + (D0 / d) ** (2 * rank))
+ cv2.imwrite(img_path, filter_img)
+ try:
+ data = {'state': 'static/media/' + name}
+ except:
+ data = {'state': 0}
+ return JsonResponse(data)
diff --git a/djangoProject/wsgi.py b/djangoProject/wsgi.py
new file mode 100644
index 0000000..315e7b7
--- /dev/null
+++ b/djangoProject/wsgi.py
@@ -0,0 +1,18 @@
+"""
+WSGI config for djangoProject project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')
+
+application = get_wsgi_application()
+
+
diff --git a/manage.py b/manage.py
new file mode 100644
index 0000000..503f50e
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/static/media/5621806f8596d4450bc1c39f20f3742.jpg b/static/media/5621806f8596d4450bc1c39f20f3742.jpg
new file mode 100644
index 0000000..ce802e7
Binary files /dev/null and b/static/media/5621806f8596d4450bc1c39f20f3742.jpg differ
diff --git a/static/media/77a271211213242fc511c61fd32a557.jpg b/static/media/77a271211213242fc511c61fd32a557.jpg
new file mode 100644
index 0000000..c0e99f9
Binary files /dev/null and b/static/media/77a271211213242fc511c61fd32a557.jpg differ
diff --git a/static/media/82474000_p5_master1200.jpg b/static/media/82474000_p5_master1200.jpg
new file mode 100644
index 0000000..3e741f9
Binary files /dev/null and b/static/media/82474000_p5_master1200.jpg differ
diff --git a/static/media/93419071_p0_master1200.jpg b/static/media/93419071_p0_master1200.jpg
new file mode 100644
index 0000000..87eff47
Binary files /dev/null and b/static/media/93419071_p0_master1200.jpg differ
diff --git a/static/media/98987580_p0_master1200.jpg b/static/media/98987580_p0_master1200.jpg
new file mode 100644
index 0000000..a672173
Binary files /dev/null and b/static/media/98987580_p0_master1200.jpg differ
diff --git a/static/media/99076089_p0_master1200.jpg b/static/media/99076089_p0_master1200.jpg
new file mode 100644
index 0000000..651d9b1
Binary files /dev/null and b/static/media/99076089_p0_master1200.jpg differ
diff --git a/static/media/99077569_p0_master1200.jpg b/static/media/99077569_p0_master1200.jpg
new file mode 100644
index 0000000..6ce51c5
Binary files /dev/null and b/static/media/99077569_p0_master1200.jpg differ
diff --git a/static/media/99549359_p0_master1200.jpg b/static/media/99549359_p0_master1200.jpg
new file mode 100644
index 0000000..7593ebd
Binary files /dev/null and b/static/media/99549359_p0_master1200.jpg differ
diff --git a/static/media/99659999_p0_master1200.jpg b/static/media/99659999_p0_master1200.jpg
new file mode 100644
index 0000000..d6b825d
Binary files /dev/null and b/static/media/99659999_p0_master1200.jpg differ
diff --git a/static/media/b59650c782cba713ba094fa72af6dff.jpg b/static/media/b59650c782cba713ba094fa72af6dff.jpg
new file mode 100644
index 0000000..489a189
Binary files /dev/null and b/static/media/b59650c782cba713ba094fa72af6dff.jpg differ
diff --git a/static/media/bd278338cfac5ff438c6f79b0dcf3e7.jpg b/static/media/bd278338cfac5ff438c6f79b0dcf3e7.jpg
new file mode 100644
index 0000000..30b9484
Binary files /dev/null and b/static/media/bd278338cfac5ff438c6f79b0dcf3e7.jpg differ
diff --git a/static/media/ffa23d028ad84cf6107a0dddd3e97ca.jpg b/static/media/ffa23d028ad84cf6107a0dddd3e97ca.jpg
new file mode 100644
index 0000000..d9fd35a
Binary files /dev/null and b/static/media/ffa23d028ad84cf6107a0dddd3e97ca.jpg differ
diff --git a/static/media/image.png b/static/media/image.png
new file mode 100644
index 0000000..c355180
Binary files /dev/null and b/static/media/image.png differ
diff --git a/static/media/wallhaven-1kejq1.jpg b/static/media/wallhaven-1kejq1.jpg
new file mode 100644
index 0000000..fefaefb
Binary files /dev/null and b/static/media/wallhaven-1kejq1.jpg differ
diff --git a/static/media/wallhaven-1kmg19.jpg b/static/media/wallhaven-1kmg19.jpg
new file mode 100644
index 0000000..f5b569d
Binary files /dev/null and b/static/media/wallhaven-1kmg19.jpg differ
diff --git a/static/media/wallhaven-3z8z7v.jpg b/static/media/wallhaven-3z8z7v.jpg
new file mode 100644
index 0000000..b4a4a71
Binary files /dev/null and b/static/media/wallhaven-3z8z7v.jpg differ
diff --git a/static/media/wallhaven-3zeyzd.jpg b/static/media/wallhaven-3zeyzd.jpg
new file mode 100644
index 0000000..0175d4e
Binary files /dev/null and b/static/media/wallhaven-3zeyzd.jpg differ
diff --git a/static/media/wallhaven-3zezd9.jpg b/static/media/wallhaven-3zezd9.jpg
new file mode 100644
index 0000000..ec758f2
Binary files /dev/null and b/static/media/wallhaven-3zezd9.jpg differ
diff --git a/static/media/wallhaven-5787d5.jpg b/static/media/wallhaven-5787d5.jpg
new file mode 100644
index 0000000..fbfd7b7
Binary files /dev/null and b/static/media/wallhaven-5787d5.jpg differ
diff --git a/static/media/wallhaven-578pl1.jpg b/static/media/wallhaven-578pl1.jpg
new file mode 100644
index 0000000..cb889d7
Binary files /dev/null and b/static/media/wallhaven-578pl1.jpg differ
diff --git a/static/media/wallhaven-57q7q1.jpg b/static/media/wallhaven-57q7q1.jpg
new file mode 100644
index 0000000..cc06007
Binary files /dev/null and b/static/media/wallhaven-57q7q1.jpg differ
diff --git a/static/media/wallhaven-6ozvgw.jpg b/static/media/wallhaven-6ozvgw.jpg
new file mode 100644
index 0000000..9645b77
Binary files /dev/null and b/static/media/wallhaven-6ozvgw.jpg differ
diff --git a/static/media/wallhaven-72k6py.jpg b/static/media/wallhaven-72k6py.jpg
new file mode 100644
index 0000000..c5726d2
Binary files /dev/null and b/static/media/wallhaven-72k6py.jpg differ
diff --git a/static/media/wallhaven-72qq29.png b/static/media/wallhaven-72qq29.png
new file mode 100644
index 0000000..3bdfbe9
Binary files /dev/null and b/static/media/wallhaven-72qq29.png differ
diff --git a/static/media/wallhaven-8o1owj.jpg b/static/media/wallhaven-8o1owj.jpg
new file mode 100644
index 0000000..7c5667d
Binary files /dev/null and b/static/media/wallhaven-8o1owj.jpg differ
diff --git a/static/media/wallhaven-8oev1j.jpg b/static/media/wallhaven-8oev1j.jpg
new file mode 100644
index 0000000..f93e3aa
Binary files /dev/null and b/static/media/wallhaven-8oev1j.jpg differ
diff --git a/static/media/wallhaven-e7ek7k.jpg b/static/media/wallhaven-e7ek7k.jpg
new file mode 100644
index 0000000..b6e9117
Binary files /dev/null and b/static/media/wallhaven-e7ek7k.jpg differ
diff --git a/static/media/wallhaven-o3m379.jpg b/static/media/wallhaven-o3m379.jpg
new file mode 100644
index 0000000..8109d58
Binary files /dev/null and b/static/media/wallhaven-o3m379.jpg differ
diff --git a/static/media/wallhaven-x8yldz.png b/static/media/wallhaven-x8yldz.png
new file mode 100644
index 0000000..8ce3e08
Binary files /dev/null and b/static/media/wallhaven-x8yldz.png differ
diff --git a/static/media/wallhaven-y8l89d.png b/static/media/wallhaven-y8l89d.png
new file mode 100644
index 0000000..036e51a
Binary files /dev/null and b/static/media/wallhaven-y8l89d.png differ
diff --git a/static/media/微信图片_20220121155949.jpg b/static/media/微信图片_20220121155949.jpg
new file mode 100644
index 0000000..0f8306c
Binary files /dev/null and b/static/media/微信图片_20220121155949.jpg differ
diff --git a/templates/upload.html b/templates/upload.html
new file mode 100644
index 0000000..f22b606
--- /dev/null
+++ b/templates/upload.html
@@ -0,0 +1,97 @@
+
+
+
+
+ Title
+
+
+
+
+
+
+
+
+
+
+
+
+
+