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