|
|
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. 求x,y方向的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方法')
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
def line_change_detection(request):
|
|
|
if request.method == 'POST':
|
|
|
para = json.loads(request.body)
|
|
|
image = para['img']
|
|
|
img = cv2.imread(PREFIX + image)
|
|
|
use_p = para['use_p']
|
|
|
|
|
|
img = cv2.GaussianBlur(img, (3, 3), 0)
|
|
|
edges = cv2.Canny(img, 50, 150, apertureSize=3)
|
|
|
if use_p:
|
|
|
linesP = cv2.HoughLinesP(edges, 1, np.pi / 180, 80, 200, 15)
|
|
|
for i_P in linesP:
|
|
|
for x1, y1, x2, y2 in i_P:
|
|
|
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 3)
|
|
|
else:
|
|
|
lines = cv2.HoughLines(edges, 1, np.pi / 2, 118)
|
|
|
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 - img.shape[0] * np.sin(theta)) / np.cos(theta)), img.shape[0])
|
|
|
cv2.line(img, pt1, pt2, (0, 0, 255))
|
|
|
else:
|
|
|
pt1 = (0, int(rho / np.sin(theta)))
|
|
|
pt2 = (img.shape[1], int((rho - img.shape[1] * np.cos(theta)) / np.sin(theta)))
|
|
|
cv2.line(img, pt1, pt2, (0, 0, 255), 1)
|
|
|
filename = getImageName() + DEFAULT_FORMAT
|
|
|
cv2.imwrite(PREFIX + filename, img)
|
|
|
return HttpResponse(filename)
|
|
|
return HttpResponse('请使用POST方法')
|
|
|
|
|
|
|
|
|
def ideal_low_filter(img, D0):
|
|
|
"""
|
|
|
生成一个理想低通滤波器(并返回)
|
|
|
"""
|
|
|
h, w = img.shape[:2]
|
|
|
filter_img = np.ones((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] = 0 if d > D0 else 1
|
|
|
return filter_img
|
|
|
|
|
|
|
|
|
def ideal_high_pass_filter(img, D0):
|
|
|
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] = 0 if d < D0 else 1
|
|
|
return filter_img
|
|
|
|
|
|
|
|
|
def butterworth_low_filter(img, D0, rank):
|
|
|
"""
|
|
|
生成一个Butterworth低通滤波器(并返回)
|
|
|
"""
|
|
|
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 + ((d / D0) ** (2 * rank)))
|
|
|
return filter_img
|
|
|
|
|
|
|
|
|
def butterworth_high_pass_filter(img, D0, rank):
|
|
|
"""
|
|
|
生成一个Butterworth低通滤波器(并返回)
|
|
|
"""
|
|
|
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)))
|
|
|
return filter_img
|
|
|
|
|
|
|
|
|
def gauss_low_pass_filter(img, d0):
|
|
|
"""
|
|
|
生成一个指数低通滤波器(并返回)
|
|
|
"""
|
|
|
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] = np.exp(-0.5 * (d ** 2) / (d0 ** 2))
|
|
|
return filter_img
|
|
|
|
|
|
|
|
|
def gauss_high_pass_filter(img, d0):
|
|
|
"""
|
|
|
生成一个指数低通滤波器(并返回)
|
|
|
"""
|
|
|
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 - np.exp(-0.5 * (d ** 2) / (d0 ** 2))
|
|
|
return filter_img
|
|
|
|
|
|
|
|
|
def filter_use_smooth(img, filter):
|
|
|
"""
|
|
|
将图像img与滤波器filter结合,生成对应的滤波图像
|
|
|
"""
|
|
|
# 首先进行傅里叶变换
|
|
|
f = np.fft.fft2(img)
|
|
|
f_center = np.fft.fftshift(f)
|
|
|
# 应用滤波器进行反变换
|
|
|
S = np.multiply(f_center, filter) # 频率相乘——l(u,v)*H(u,v)
|
|
|
f_origin = np.fft.ifftshift(S) # 将低频移动到原来的位置
|
|
|
f_origin = np.fft.ifft2(f_origin) # 使用ifft2进行傅里叶的逆变换
|
|
|
f_origin = np.abs(f_origin) # 设置区间
|
|
|
return f_origin
|
|
|
|
|
|
|
|
|
def filter_use_sharpen(img, filter):
|
|
|
f = np.fft.fft2(img)
|
|
|
f_center = np.fft.fftshift(f)
|
|
|
# 应用滤波器进行反变换
|
|
|
S = np.multiply(f_center, filter) # 频率相乘——l(u,v)*H(u,v)
|
|
|
f_origin = np.fft.ifftshift(S) # 将低频移动到原来的位置
|
|
|
f_origin = np.fft.ifft2(f_origin) # 使用ifft2进行傅里叶的逆变换
|
|
|
f_origin = np.abs(f_origin) # 设置区间
|
|
|
f_origin = f_origin / np.max(f_origin.all())
|
|
|
return f_origin
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
def smooth(request):
|
|
|
if request.method == 'POST':
|
|
|
para = json.loads(request.body)
|
|
|
image = para['img']
|
|
|
img = cv2.imread(PREFIX + image, 0)
|
|
|
# frequency domain
|
|
|
fd = para['fd']
|
|
|
filter = para['filter']
|
|
|
if fd:
|
|
|
if filter == 'ideal_low_pass_filter':
|
|
|
d0 = para.get('d0', 20)
|
|
|
img = filter_use_smooth(img, ideal_low_filter(img, d0))
|
|
|
elif filter == 'butterworth_low_pass_filter':
|
|
|
d0 = para.get('d0', 20)
|
|
|
rank = para.get('rank', 2)
|
|
|
img = filter_use_smooth(img, butterworth_low_filter(img, d0, rank))
|
|
|
elif filter == 'gauss_low_pass_filter':
|
|
|
d0 = para.get('d0', 20)
|
|
|
img = filter_use_smooth(img, gauss_low_pass_filter(img, d0))
|
|
|
else:
|
|
|
size = para['size']
|
|
|
if filter == 'average':
|
|
|
img = cv2.blur(img, (size, size))
|
|
|
elif filter == 'median':
|
|
|
img = cv2.medianBlur(img, size)
|
|
|
filename = getImageName() + DEFAULT_FORMAT
|
|
|
cv2.imwrite(PREFIX + filename, img)
|
|
|
return HttpResponse(filename)
|
|
|
return HttpResponse('请使用POST方法')
|
|
|
|
|
|
|
|
|
def process_roberts(img):
|
|
|
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)
|
|
|
# 转uint8
|
|
|
absX = cv2.convertScaleAbs(x)
|
|
|
absY = cv2.convertScaleAbs(y)
|
|
|
return cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
|
|
|
|
|
|
|
|
|
def process_sobel(img):
|
|
|
x = cv2.Sobel(img, cv2.CV_16S, 1, 0) # 对x求一阶导
|
|
|
y = cv2.Sobel(img, cv2.CV_16S, 0, 1) # 对y求一阶导
|
|
|
absX = cv2.convertScaleAbs(x)
|
|
|
absY = cv2.convertScaleAbs(y)
|
|
|
return cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
|
|
|
|
|
|
|
|
|
def process_prewitt(img):
|
|
|
kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)
|
|
|
kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)
|
|
|
x = cv2.filter2D(img, cv2.CV_16S, kernelx)
|
|
|
y = cv2.filter2D(img, cv2.CV_16S, kernely)
|
|
|
# 转uint8
|
|
|
absX = cv2.convertScaleAbs(x)
|
|
|
absY = cv2.convertScaleAbs(y)
|
|
|
return cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
|
|
|
|
|
|
|
|
|
def process_laplacian(img):
|
|
|
dst = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
|
|
|
return cv2.convertScaleAbs(dst)
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
def sharpen(request):
|
|
|
if request.method == 'POST':
|
|
|
para = json.loads(request.body)
|
|
|
image = para['img']
|
|
|
img = cv2.imread(PREFIX + image, 0)
|
|
|
# frequency domain
|
|
|
fd = para['fd']
|
|
|
filter = para['filter']
|
|
|
if fd:
|
|
|
if filter == 'ideal_high_pass_filter':
|
|
|
d0 = para.get('d0', 40)
|
|
|
img = filter_use_sharpen(img, ideal_high_pass_filter(img, d0))
|
|
|
elif filter == 'butterworth_high_pass_filter':
|
|
|
d0 = para.get('d0', 20)
|
|
|
rank = para.get('rank', 2)
|
|
|
img = filter_use_sharpen(img, butterworth_high_pass_filter(img, d0, rank))
|
|
|
elif filter == 'gauss_high_pass_filter':
|
|
|
d0 = para.get('d0', 20)
|
|
|
img = filter_use_sharpen(img, gauss_high_pass_filter(img, d0))
|
|
|
else:
|
|
|
if filter == 'Roberts':
|
|
|
img = process_roberts(img)
|
|
|
elif filter == 'Sobel':
|
|
|
img = process_sobel(img)
|
|
|
elif filter == 'Prewitt':
|
|
|
img = process_prewitt(img)
|
|
|
elif filter == 'Laplacian':
|
|
|
img = process_laplacian(img)
|
|
|
filename = getImageName() + DEFAULT_FORMAT
|
|
|
cv2.imwrite(PREFIX + filename, img)
|
|
|
return HttpResponse(filename)
|
|
|
return HttpResponse('请使用POST方法')
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
def morphology(request):
|
|
|
if request.method == 'POST':
|
|
|
para = json.loads(request.body)
|
|
|
image = para['img']
|
|
|
size = para.get('size', 5)
|
|
|
img = cv2.imread(PREFIX + image, cv2.IMREAD_UNCHANGED)
|
|
|
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (size, size))
|
|
|
op = para['type']
|
|
|
if op == 'open':
|
|
|
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
|
|
|
elif op == 'close':
|
|
|
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
|
|
|
elif op == 'erode':
|
|
|
img = cv2.erode(img, kernel)
|
|
|
elif op == 'dilate':
|
|
|
img = cv2.dilate(img, kernel)
|
|
|
filename = getImageName() + DEFAULT_FORMAT
|
|
|
cv2.imwrite(PREFIX + filename, img)
|
|
|
return HttpResponse(filename)
|
|
|
return HttpResponse('请使用POST方法')
|
|
|
|
|
|
|
|
|
def r(request):
|
|
|
return render(request, 'upload.html')
|