You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

562 lines
19 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import json
import uuid
import cv2
import matplotlib.pyplot as plt
import numpy as np
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from django.views.decorators.csrf import csrf_exempt
PREFIX = 'media/'
DEFAULT_FORMAT = '.jpg'
SUPPORT_FILE_FORMAT = ['png', 'jpg', 'bmp', 'jpeg', 'jpe', 'dib', 'pbm', 'pgm', 'ppm', 'tiff', 'tif']
# 获取uuid图片名
def getImageName():
return uuid.uuid1().__str__()
# 保存图片,并判断是否为合适的扩展名
def getImage(request):
print(request.FILES)
file = request.FILES.get('image')
suffix = file.name[file.name.rfind('.') + 1:].lower()
if suffix not in SUPPORT_FILE_FORMAT:
return ''
filename = getImageName() + '.' + suffix
img = open(PREFIX + filename, 'wb+')
for chunk in file.chunks():
img.write(chunk)
img.close()
return filename
# 接收图片转发到getImage
@csrf_exempt
def upload(request):
imageName = getImage(request)
if imageName == '':
return HttpResponse('Not supported image format')
return HttpResponse(imageName)
def process_bg():
img = np.zeros((800, 800, 3), np.uint8)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, img)
return filename
def process_line(para):
name, start, end, color, thickness = para['img'], para['start'], para['end'], para['color'], para['thickness']
img = cv2.imread(PREFIX + name)
cv2.line(img, tuple(start), tuple(end), tuple(color), thickness)
cv2.imwrite(PREFIX + name, img)
return name
def process_rectangle(para):
name, start, end, color, thickness = para['img'], para['start'], para['end'], para['color'], para['thickness']
img = cv2.imread(PREFIX + name)
cv2.rectangle(img, tuple(start), tuple(end), tuple(color), thickness)
cv2.imwrite(PREFIX + name, img)
return name
def process_circle(para):
name, center, radius, color, thickness = para['img'], para['center'], para['radius'], para['color'], para[
'thickness']
img = cv2.imread(PREFIX + name)
cv2.circle(img, tuple(center), radius, tuple(color), thickness)
cv2.imwrite(PREFIX + name, img)
return name
def process_ellipse(para):
name, center, axes, angle, startangle, endangle, color, thickness = para['img'], para['center'], para['axes'], para[
'angle'], para['startangle'], para['endangle'], para['color'], para['thickness']
img = cv2.imread(PREFIX + name)
cv2.ellipse(img, tuple(center), tuple(axes), angle, startangle, endangle, tuple(color), thickness)
cv2.imwrite(PREFIX + name, img)
return name
def process_polylines(para):
name, point, isclosed, color = para['img'], para['point'], para['isclosed'], para['color']
img = cv2.imread(PREFIX + name)
pts = np.array(point, np.int32)
pts = pts.reshape((-1, 1, 2))
cv2.polylines(img, [pts], isclosed, tuple(color))
cv2.imwrite(PREFIX + name, img)
return name
def process_text(para):
name, text, org, fontsize, color = para['img'], para['text'], para['org'], para['fontsize'], para['color']
img = cv2.imread(PREFIX + name)
cv2.putText(img, text, org, fontFace=cv2.FONT_HERSHEY_SCRIPT_COMPLEX, fontScale=fontsize, color=tuple(color))
cv2.imwrite(PREFIX + name, img)
return name
# 使用opencv 基本绘图
@csrf_exempt
def basic_drawing(request):
if request.method == 'POST':
para = json.loads(request.body)
draw_type = para['type']
if draw_type == 'bg':
return HttpResponse(process_bg())
else:
if draw_type == 'line':
return HttpResponse(process_line(para))
elif draw_type == 'rectangle':
return HttpResponse(process_rectangle(para))
elif draw_type == 'circle':
return HttpResponse(process_circle(para))
elif draw_type == 'ellipse':
return HttpResponse(process_ellipse(para))
elif draw_type == 'polylines':
return HttpResponse(process_polylines(para))
elif draw_type == 'text':
return HttpResponse(process_text(para))
return HttpResponse('请使用POST方法')
def process_filter_rgb(para, data):
limit = para.get('limit', 100)
c_range = para.get('range', [90, 230])
if np.max(data) > limit:
data = data * (255 / np.max(data))
tmp = np.zeros_like(data)
tmp[((data > c_range[0]) & (data <= c_range[1]))] = 255
return tmp
@csrf_exempt
def rgb_color_space(request, color):
if request.method == 'POST':
para = json.loads(request.body)
image_name = para['img']
img = cv2.imread(PREFIX + image_name)
data = None
if color == 'r':
data = img[:, :, 2]
elif color == 'g':
data = img[:, :, 1]
elif color == 'b':
data = img[:, :, 0]
if para.get('filter', False):
data = process_filter_rgb(para, data)
filename = color + '-' + image_name
cv2.imwrite(PREFIX + filename, data)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
@csrf_exempt
def hsv_color_space(request, color):
if request.method == 'POST':
para = json.loads(request.body)
image_name = para['img']
img = cv2.imread(PREFIX + image_name)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
data = None
if color == 'h':
data = hsv[:, :, 0]
elif color == 's':
data = hsv[:, :, 1]
elif color == 'v':
data = hsv[:, :, 2]
elif color == 'filter':
upper_bound = para.get('ub', [0, 0, 0])
lower_bound = para.get('lb', [200, 40, 100])
data = cv2.inRange(hsv, np.array(upper_bound), np.array(lower_bound))
filename = color + '-' + image_name
cv2.imwrite(PREFIX + filename, data)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
def logic_and(img, has_color, base):
if base == 2:
img[0], img[1] = img[1], img[0]
img1 = cv2.imread(PREFIX + img[0], has_color)
img2 = cv2.imread(PREFIX + img[1], has_color)
rows, cols = img1.shape[:2]
img2 = cv2.resize(img2, (cols, rows), interpolation=cv2.INTER_CUBIC)
ret = img1 & img2
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
def logic_or(img, has_color, base):
if base == 2:
img[0], img[1] = img[1], img[0]
img1 = cv2.imread(PREFIX + img[0], has_color)
img2 = cv2.imread(PREFIX + img[1], has_color)
rows, cols = img1.shape[:2]
img2 = cv2.resize(img2, (cols, rows), interpolation=cv2.INTER_CUBIC)
ret = img1 | img2
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
def logic_not(img, has_color, base):
if base == 2:
img[0], img[1] = img[1], img[0]
image = cv2.imread(PREFIX + img[0], has_color)
ret = ~image
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
def arithmetic_add(img, has_color, base):
if base == 2:
img[0], img[1] = img[1], img[0]
img1 = cv2.imread(PREFIX + img[0], has_color)
img2 = cv2.imread(PREFIX + img[1], has_color)
rows, cols = img1.shape[:2]
img2 = cv2.resize(img2, (cols, rows), interpolation=cv2.INTER_CUBIC)
ret = cv2.add(img1, img2)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
def arithmetic_sub(img, has_color, base):
img1 = cv2.imread(PREFIX + img[0], has_color)
img2 = cv2.imread(PREFIX + img[1], has_color)
if base == 1:
rows, cols = img1.shape[:2]
img2 = cv2.resize(img2, (cols, rows), interpolation=cv2.INTER_CUBIC)
elif base == 2:
rows, cols = img2.shape[:2]
img1 = cv2.resize(img1, (cols, rows), interpolation=cv2.INTER_CUBIC)
ret = cv2.subtract(img1, img2)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
def arithmetic_multi(img, has_color, base):
if base == 2:
img[0], img[1] = img[1], img[0]
img1 = cv2.imread(PREFIX + img[0], has_color)
img2 = cv2.imread(PREFIX + img[1], has_color)
rows, cols = img1.shape[:2]
img2 = cv2.resize(img2, (cols, rows), interpolation=cv2.INTER_CUBIC)
ret = cv2.multiply(img1, img2)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
def arithmetic_div(img, has_color, base):
img1 = cv2.imread(PREFIX + img[0], has_color)
img2 = cv2.imread(PREFIX + img[1], has_color)
if base == 1:
rows, cols = img1.shape[:2]
img2 = cv2.resize(img2, (cols, rows), interpolation=cv2.INTER_CUBIC)
elif base == 2:
rows, cols = img2.shape[:2]
img1 = cv2.resize(img1, (cols, rows), interpolation=cv2.INTER_CUBIC)
ret = cv2.divide(img1, img2)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, ret)
return filename
@csrf_exempt
def basic_operation(request):
if request.method == 'POST':
para = json.loads(request.body)
operator = para['operator']
img = para['img']
has_color = para['color']
base = para['base']
if operator == 'and':
return HttpResponse(logic_and(img, has_color, base))
elif operator == 'or':
return HttpResponse(logic_or(img, has_color, base))
elif operator == 'not':
return HttpResponse(logic_not(img, has_color, base))
elif operator == 'add':
return HttpResponse(arithmetic_add(img, has_color, base))
elif operator == 'sub':
return HttpResponse(arithmetic_sub(img, has_color, base))
elif operator == 'multi':
return HttpResponse(arithmetic_multi(img, has_color, base))
elif operator == 'div':
return HttpResponse(arithmetic_div(img, has_color, base))
return HttpResponse('请使用POST方法')
@csrf_exempt
def resize(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image)
size = para.get('size', None)
if size is not None:
width = img.shape[0]
height = img.shape[1]
interpolation = None
if width * height >= size[0] * size[1]:
interpolation = cv2.INTER_AREA
else:
interpolation = cv2.INTER_CUBIC
img = cv2.resize(img, tuple(size), interpolation)
else:
multiple = para['multiple']
if multiple < 1:
interpolation = cv2.INTER_AREA
else:
interpolation = cv2.INTER_CUBIC
img = cv2.resize(img, (0, 0), fx=multiple, fy=multiple, interpolation=interpolation)
new_filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + new_filename, img)
return HttpResponse(new_filename)
return HttpResponse('请使用POST方法')
def rotate_bound(image, angle):
(h, w) = image.shape[:2]
(cX, cY) = (w // 2, h // 2)
M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY
return cv2.warpAffine(image, M, (nW, nH))
@csrf_exempt
def rotate(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image)
angle = para['angle']
img = rotate_bound(img, angle)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, img)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
@csrf_exempt
def translation(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image)
offset = para['offset']
height, width = img.shape[:2]
M = np.float32([[1, 0, offset[0]], [0, 1, offset[1]]])
img = cv2.warpAffine(img, M, (width, height))
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, img)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
@csrf_exempt
def flip(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image)
flip_code = para.get('flip', 1)
img = cv2.flip(img, flip_code)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, img)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
@csrf_exempt
def affine(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image)
before = np.float32(para['before'])
after = np.float32(para['after'])
rows, cols = img.shape[:2]
M = cv2.getAffineTransform(before, after)
img = cv2.warpAffine(img, M, (rows, cols))
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, img)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
def hist_cover_gray(img, fileName):
plt.figure(fileName, figsize=(16, 8))
hist = cv2.calcHist([img], [0], None, [256], [0, 255])
plt.plot(hist)
plt.xlim([0, 255])
plt.savefig(fileName)
def hist_cover_rgb(img, fileName):
color = ["r", "g", "b"]
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(fileName)
@csrf_exempt
def histogram(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
color = para['color']
histogram_name = getImageName() + DEFAULT_FORMAT
if color:
img = cv2.imread(PREFIX + image)
hist_cover_rgb(img, PREFIX + histogram_name)
else:
img = cv2.imread(PREFIX + image, 0)
hist_cover_gray(img, PREFIX + histogram_name)
return HttpResponse(histogram_name)
return HttpResponse('请使用POST方法')
def grayHist(img, filename):
plt.figure(filename, figsize=(16, 8))
h, w = img.shape[:2]
pixelSequence = img.reshape(h * w, 1)
numberBins = 256
histogram, bins, patch = plt.hist(pixelSequence, numberBins)
plt.xlabel("gray label")
plt.ylabel("number of pixels")
plt.axis([0, 255, 0, np.max(histogram)])
# 打印输出峰值
plt.savefig(filename)
@csrf_exempt
def piecewise_linear_transform(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image, 0)
funcs = para['func']
ret_name1 = getImageName() + DEFAULT_FORMAT
ret_name2 = getImageName() + DEFAULT_FORMAT
out_name = getImageName() + DEFAULT_FORMAT
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]
last_limit = float("-inf")
for func in funcs:
limit = func['limit']
k = func['k']
b = func['b']
if limit == -1:
if pix > last_limit:
out[i][j] = k * pix + b
else:
if last_limit <= pix < limit:
out[i][j] = k * pix + b
last_limit = limit
out = np.around(out).astype(np.uint8)
cv2.imwrite(PREFIX + out_name, out)
grayHist(img, PREFIX + ret_name1)
grayHist(out, PREFIX + ret_name2)
return HttpResponse([{"orig": image, "hist": ret_name1}, {"orig": out_name, "hist": ret_name2}])
return HttpResponse('请使用POST方法')
@csrf_exempt
def edge_detection(request):
if request.method == 'POST':
para = json.loads(request.body)
image = para['img']
img = cv2.imread(PREFIX + image, 0)
operator = para['operator']
if operator == 'Roberts':
kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
kernely = np.array([[0, -1], [1, 0]], dtype=int)
x = cv2.filter2D(img, cv2.CV_16S, kernelx)
y = cv2.filter2D(img, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
img = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
elif operator == 'Sobel':
x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
img = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
elif operator == 'Laplacian':
img_gaussianBlur = cv2.GaussianBlur(img, (5, 5), 0)
dst = cv2.Laplacian(img_gaussianBlur, cv2.CV_16S, ksize=3)
img = cv2.convertScaleAbs(dst)
elif operator == 'LoG':
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.copyMakeBorder(grayImage, 2, 2, 2, 2, borderType=cv2.BORDER_REPLICATE)
img = cv2.GaussianBlur(img, (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]],
dtype=np.int32)
image1 = np.zeros(img.shape).astype(np.int32)
h, w, _ = img.shape
for i in range(2, h - 2):
for j in range(2, w - 2):
image1[i, j] = np.sum(m1 * img[i - 2:i + 3, j - 2:j + 3, 1])
img = cv2.convertScaleAbs(image1)
elif operator == 'Canny':
tmp = cv2.GaussianBlur(img, (3, 3), 0)
# 3. 求xy方向的Sobel算子
gradx = cv2.Sobel(tmp, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(tmp, cv2.CV_16SC1, 0, 1)
# 4. 使用Canny函数处理图像x,y分别是3求出来的梯度低阈值50高阈值150
img = cv2.Canny(gradx, grady, 50, 150)
elif operator == 'Enhance':
h, w = img.shape
gradient = np.zeros((h, w))
img = img.astype('float')
for i in range(h - 1):
for j in range(w - 1):
gx = abs(img[i + 1, j] - img[i, j])
gy = abs(img[i, j + 1] - img[i, j])
gradient[i, j] = gx + gy
sharp = img + gradient
sharp = np.where(sharp > 255, 255, sharp)
sharp = np.where(sharp < 0, 0, sharp)
gradient = gradient.astype('uint8')
sharp = sharp.astype('uint8')
sharp_name = getImageName() + DEFAULT_FORMAT
gradient_name = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + sharp_name, sharp)
cv2.imwrite(PREFIX + gradient_name, gradient)
ret = [{"sharp": sharp_name, "gradient": gradient_name}]
return HttpResponse(ret)
filename = getImageName() + DEFAULT_FORMAT
cv2.imwrite(PREFIX + filename, img)
return HttpResponse(filename)
return HttpResponse('请使用POST方法')
def r(request):
return render(request, 'upload.html')