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.

270 lines
10 KiB

from removebg import RemoveBg
from django.http import JsonResponse
from django.views.decorators.http import require_POST,require_GET
from matplotlib import pyplot as plt
import sys
import imutils
from PIL import Image
sys.path.append("../")
import urllib.request
import base64
import cv2
import numpy as np
import numba as nb
from pyzbar.pyzbar import decode
# base64转cv
def base64tocv(imagecode):
strList = str(imagecode).split(',')
b64_img = ''
for i in strList[1:]:
b64_img += i
imgString = base64.b64decode(b64_img)
nparr = np.fromstring(imgString, np.uint8)
image = cv2.imdecode(nparr, cv2.COLOR_RGB2BGR)
# image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return image
# #cv 转 base64
# def cvtobase64(img):
# #
# # image = cv2.imencode('.jpg', img)[1]
# # res_bs64 = str(base64.b64encode(image))[2:-1]
# res_b = cv2.imencode('.jpg', img)[1].tostring()
# res_bs64 = base64.b64encode(res_b)
# return res_bs64
#InMemoryUploadedFile 转 ndarray
def getNdarraybyInMemoryUploadedFile(uploaded_file):
fileinbytes = uploaded_file.file
img_np_arr = np.frombuffer(fileinbytes.read(), np.uint8)
return cv2.imdecode(img_np_arr, cv2.IMREAD_COLOR)
#ndarray 转 base64
def getbase64byndarray(pic_img):
retval, buffer = cv2.imencode('.jpg', pic_img)
pic_str = base64.b64encode(buffer)
return pic_str.decode()
# 获取图像并返回
@require_POST
def getPicture(request):
if(not request.FILES):
response = urllib.request.urlopen(request.POST.get("files"))
img_array = np.array(bytearray(response.read()), dtype=np.uint8)
cv_image = cv2.imdecode(img_array, -1)
elif(not request.POST):
print(request.FILES)
image = request.FILES.get('files')
cv_image = getNdarraybyInMemoryUploadedFile(image)
height,width,color = cv_image.shape
base64_image=getbase64byndarray(cv_image)
return JsonResponse(data={"image": base64_image,"height": height,"width": width}, json_dumps_params={'ensure_ascii': False})
# 放大/缩小图片
@require_POST
def resizePicture(request):
image = request.POST.get('files')
cv_image = base64tocv(image);
height,width,colors=cv_image.shape
if(request.POST.get("height") is None):
base64_image=getbase64byndarray(cv_image)
return JsonResponse(data={"image": base64_image,"height":height,"width":width}, json_dumps_params={'ensure_ascii': False})
height=request.POST.get("height")
width=request.POST.get("width")
resize_image = cv2.resize(cv_image, (int(width), int(height)),interpolation=cv2.INTER_LINEAR)
height, width, colors = resize_image.shape
resize_image=getbase64byndarray(resize_image)
return JsonResponse(data={"image": resize_image,"height":height,"width":width}, json_dumps_params={'ensure_ascii': False})
# 翻转图片
@require_POST
def mirrorPicture(request):
image = request.POST.get('files')
cv_image = base64tocv(image);
direction=request.POST.get('direction')
if(direction=='0'):
cv_image = cv2.flip(cv_image, 1, dst=None)
elif(direction=='1'):
cv_image = cv2.flip(cv_image,0,dst=None)
elif(direction=='2'):
cv_image = cv2.flip(cv_image,-1,dst=None)
mirror_image=getbase64byndarray(cv_image)
return JsonResponse(data={"image": mirror_image}, json_dumps_params={'ensure_ascii': False})
# 旋转图片
@require_POST
def rotatePicture(request):
image = request.POST.get('files')
cv_image = base64tocv(image)
rows, cols, depth = cv_image.shape
(cX, cY) = (cols // 2, rows // 2)
direction=request.POST.get('direction')
if(direction=='left'):
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])
nW = int((rows * sin) + (cols * cos))
nH = int((rows * cos) + (cols * sin))
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY
cv_image = cv2.warpAffine(cv_image, M, (nW, nH),borderValue=(255,255,255))
elif(direction=='right'):
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), -90, 1)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])
nW = int((rows * sin) + (cols * cos))
nH = int((rows * cos) + (cols * sin))
M[0, 2] += (nW / 2) - cX
M[1, 2] += (nH / 2) - cY
cv_image = cv2.warpAffine(cv_image, M, (nW, nH),borderValue=(255,255,255))
rotate_image=getbase64byndarray(cv_image)
return JsonResponse(data={"image": rotate_image}, json_dumps_params={'ensure_ascii': False})
#抠图
@require_POST
def keying(request):
rmbg = RemoveBg("XHfvSY3phCVna4NZj8Tr8Wnz", "error.log")
image = request.POST.get('files')
rmbg.remove_background_from_base64_img(image,new_file_name="output.jpg",bg_color=(0,0,0))
result=cv2.imread("output.jpg")
result=getbase64byndarray(result)
return JsonResponse(data={"image": result}, json_dumps_params={'ensure_ascii': False})
#图像平滑
@require_POST
def smooth(request):
base_image = request.POST.get('files')
cv_image=base64tocv(base_image)
imgarray = np.array(cv_image)
height, width = imgarray.shape[0], imgarray.shape[1]
edge = int((3 - 1) / 2)
if height - 1 - edge <= edge or width - 1 - edge <= edge:
print("the kenerl is to long")
return None
for i in range(height):
for j in range(width):
if i <= edge - 1 or i >= height - 1 - edge or j <= edge - 1 or j >= height - 1 - edge:
imgarray[i][j] = imgarray[i][j]
else:
num = []
for m in range(i - edge, i + edge + 1):
for n in range(j - edge, j + edge + 1):
num.append((imgarray[m][n])[0]) # 这里通过彩色图像第一个值计算中值也可以改为第二个或者第三个
temp = np.median(num)
idex_tem = num.index(temp) # 获取中值在数组中的坐标
l1 = int((idex_tem / 3)) - edge + i # 根据进制转换反推出中值在图像中的坐标
l2 = (idex_tem % 3) - edge + j
imgarray[i][j] = imgarray[l1][l2] # 赋值
# num1 = np.sort(num)[int(self.k * self.k / 2)]
# print(idex_tem)
# temp = np.median(imgarray[i][j], imgarray[i - edge][j], imgarray[i - edge][j])
# imgarray[i][j] = np.median(imgarray[i - edge:i + edge + 1, j -edge:j+edge + 1])
new_img = Image.fromarray(imgarray)
result=getbase64byndarray(imgarray)
return JsonResponse(data={"image": result}, json_dumps_params={'ensure_ascii': False})
#曝光调整
def exposure(request):
img = request.POST.get('files')
image = base64tocv(img)
# chans = cv2.split(image)
# colors = ("b", "g", "r")
# for (chan, color) in zip(chans, colors):
# hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
# # plt.plot(hist, color=color)
# # plt.xlim([0, 256])
# plt.subplot(4, 2, 5)
equalizeOver = np.zeros(image.shape, image.dtype)
equalizeOver[:, :, 0] = cv2.equalizeHist(image[:, :, 0])
equalizeOver[:, :, 1] = cv2.equalizeHist(image[:, :, 1])
equalizeOver[:, :, 2] = cv2.equalizeHist(image[:, :, 2])
output = getbase64byndarray(equalizeOver)
return JsonResponse(data={"image": output}, json_dumps_params={'ensure_ascii': False})
#锐化
def sharpen(request):
img = request.POST.get('files')
image = base64tocv(img)
sharpen_op = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], dtype=np.float32)
# sharpen_op = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]], dtype=np.float32)
sharpen_image = cv2.filter2D(image, cv2.CV_32F, sharpen_op)
sharpen_image = cv2.convertScaleAbs(sharpen_image)
output = getbase64byndarray(sharpen_image)
return JsonResponse(data={"image": output}, json_dumps_params={'ensure_ascii': False})
#识别条形码
def barCode(request):
img = request.POST.get('files')
image = base64tocv(img)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Image", gray)
cv2.waitKey(0)
# 计算图片x和y方向的Scharr梯度大小
ddepth = cv2.cv.CV_32F if imutils.is_cv2() else cv2.CV_32F
gradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1)
# 用x方向的梯度减去y方向的梯度
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
cv2.imshow("gradient", gradient)
cv2.waitKey(0)
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 180, 255, cv2.THRESH_BINARY)
cv2.imshow("blur", blurred)
cv2.waitKey(0)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
#  构造一个闭合核并应用于阈值图片
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 10))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
cv2.imshow("closed", closed)
cv2.waitKey(0)
# 执行一系列的腐蚀和膨胀操作
closed = cv2.dilate(closed, None, iterations=4)
closed = cv2.erode(closed, None, iterations=4)
cv2.imshow("Image", closed)
cv2.waitKey(0)
# 找到阈值化后图片中的轮廓,然后进行根据区域进行排序,仅保留最大区域
cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
# 计算最大轮廓的旋转边界框
rect = cv2.minAreaRect(c)
box = cv2.cv.BoxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect)
box = np.int0(box)
# 在检测到的条形码周围绘制边界框并显示图片
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
result=getbase64byndarray(image)
return JsonResponse(data={"image": result}, json_dumps_params={'ensure_ascii': False})
#噪声去除
def removeNoise(request):
img = request.POST.get('files')
img = base64tocv(img)
specular = cv2.fastNlMeansDenoisingColored(img, None, 10, 5, 7, 21)
result = getbase64byndarray(specular)
return JsonResponse(data={"image": result}, json_dumps_params={'ensure_ascii': False})