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.

584 lines
18 KiB

import math
import random
import uuid
import cv2
import matplotlib.pyplot as plt
import numpy as np
from django.http import HttpResponse
PREFIX = 'media/'
DEFAULT_FORMAT = '.jpg'
SUPPORT_FILE_FORMAT = ['png', 'jpg', 'bmp', 'jpeg', 'jpe', 'dib', 'pbm', 'pgm', 'ppm', 'tiff', 'tif']
def get_image_name():
return uuid.uuid1().__str__()
def get_image(request):
file = request.FILES.get('image')
suffix = file.name[file.name.rfind('.') + 1:].lower()
if suffix not in SUPPORT_FILE_FORMAT:
return ''
filename = get_image_name() + '.' + suffix
img = open(PREFIX + filename, 'wb+')
for chunk in file.chunks():
img.write(chunk)
img.close()
return filename
def process_bg():
img = np.zeros((800, 800, 3), np.uint8)
return save_image(img)
def process_line(para):
name, start, end, color, thickness = para['img'], para['start'], para['end'], \
para.get('color', [255, 255, 255]), para.get('thickness', 20)
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.get('color', [255, 255, 255]), para.get('thickness', 20)
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.get('color', [255, 255, 255]), para.get('thickness', 20)
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.get('angle', 0), \
para.get('startangle', 0), \
para.get('endangle', 360), \
para.get('color', [255, 255, 255]), \
para.get('thickness', 20)
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.get('isclosed', True), \
para.get('color', [255, 255, 255])
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.get('fontsize', 14), para.get('color', [255, 255, 255])
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
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
def base2read(img, has_color):
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)
return img1, img2
def logic_and(img, has_color, base):
img1 = None
img2 = None
if base == 2:
img1, img2 = base2read(img, has_color)
ret = img1 & img2
return save_image(ret)
def logic_or(img, has_color, base):
img1 = None
img2 = None
if base == 2:
img1, img2 = base2read(img, has_color)
ret = img1 | img2
return save_image(ret)
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
return save_image(ret)
def arithmetic_add(img, has_color, base):
img1 = None
img2 = None
if base == 2:
img1, img2 = base2read(img, has_color)
ret = cv2.add(img1, img2)
return save_image(ret)
def base2read_choice(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)
return img1, img2
def arithmetic_sub(img, has_color, base):
img1, img2 = base2read_choice(img, has_color, base)
ret = cv2.subtract(img1, img2)
return save_image(ret)
def arithmetic_multi(img, has_color, base):
img1 = None
img2 = None
if base == 2:
img1, img2 = base2read(img, has_color)
ret = cv2.multiply(img1, img2)
return save_image(ret)
def arithmetic_div(img, has_color, base):
img1, img2 = base2read_choice(img, has_color, base)
ret = cv2.divide(img1, img2)
return save_image(ret)
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))
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)
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)
def process_LoG(img):
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])
return cv2.convertScaleAbs(image1)
def process_Canny(img):
tmp = cv2.GaussianBlur(img, (3, 3), 0)
gradx = cv2.Sobel(tmp, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(tmp, cv2.CV_16SC1, 0, 1)
return cv2.Canny(gradx, grady, 50, 150)
def process_enhance(img):
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')
ret = [{"sharp": save_image(sharp), "gradient": save_image(gradient)}]
return HttpResponse(ret)
def process_lcd_with_p(edges, img):
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)
return img
def process_lcd_without_p(edges, img):
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)
return img
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_pass_filter(img, D0, rank):
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):
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, my_filter):
# 首先进行傅里叶变换
f = np.fft.fft2(img)
f_center = np.fft.fftshift(f)
# 应用滤波器进行反变换
S = np.multiply(f_center, my_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, my_filter):
f_origin = filter_use_smooth(img, my_filter)
f_origin = f_origin / np.max(f_origin.all())
return f_origin
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)
def process_gauss_noise(img):
img = np.array(img / 255, dtype=float)
noise_ = np.random.normal(0, 0.1, img.shape)
img = img + noise_
img = np.clip(img, 0.0, 1.0)
return np.uint8(img * 255)
def process_salt_and_peper_noise(img, para):
range_salt = para.get('salt', 0.2)
range_peper = para.get('peper', 0.8)
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
rdn = random.random()
if rdn < range_salt:
output[i][j] = 0
elif rdn > range_peper:
output[i][j] = 255
else:
output[i][j] = img[i][j]
return output
def process_geometric_mean(img):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
ji = 1.0
for m in range(-1, 2):
if 0 <= j + m < img.shape[1]:
ji *= img[i][j + m]
output[i][j] = math.pow(ji, 1 / 3)
return output
def process_arithmetic_mean(img):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
my_sum = 0
for m in range(-1, 2):
for n in range(-1, 2):
if 0 <= i + m < img.shape[0] and 0 <= j + n < img.shape[1]:
my_sum += img[i + m][j + n]
output[i][j] = int(my_sum / 9)
return output
def process_harmonic_filter(img):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
my_sum = 0
for m in range(-1, 2):
for n in range(-1, 2):
if 0 <= i + m < img.shape[0] and 0 <= j + n < img.shape[1]:
my_sum += 1 / img[i + m][j + n]
output[i][j] = int(9 / my_sum)
return output
def get_middle(array):
length = len(array)
for i in range(length):
for j in range(i + 1, length):
if array[j] > array[i]:
temp = array[j]
array[j] = array[i]
array[i] = temp
return array[int(length / 2)]
def get_array_from_struct_ele(img, i, j):
array = []
for m in range(-1, 2):
for n in range(-1, 2):
if 0 <= i + m < img.shape[0] and 0 <= j + n < img.shape[1]:
array.append(img[i + m][j + n])
return array
def process_max_sort(img):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
array = get_array_from_struct_ele(img, i, j)
array.sort(reverse=True)
output[i][j] = max(array[0], img[i][j])
return output
def process_min_sort(img):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
array = get_array_from_struct_ele(img, i, j)
array.sort()
output[i][j] = min(array[0], img[i][j])
return output
def process_median_sort(img):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
array = get_array_from_struct_ele(img, i, j)
output[i][j] = get_middle(array)
return output
def process_high_choice(img, limit):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if img[i][j] > limit:
output[i][j] = img[i][j]
else:
output[i][j] = 0
return output
def process_low_choice(img, limit):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if img[i][j] < limit:
output[i][j] = img[i][j]
else:
output[i][j] = 0
return output
def process_pass_choice(img, my_min, my_max):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if my_min < img[i][j] < my_max:
output[i][j] = img[i][j]
else:
output[i][j] = 255
return output
def process_stop_choice(img, my_min, my_max):
output = np.zeros(img.shape, np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if my_min < img[i][j] < my_max:
output[i][j] = 0
else:
output[i][j] = img[i][j]
return output
def save_image(img, prefix=None):
img_name = get_image_name() + DEFAULT_FORMAT
if prefix is None:
cv2.imwrite(PREFIX + img_name, img)
else:
cv2.imwrite(prefix + img_name, img)
return img_name