diff --git a/extra.py b/extra.py new file mode 100644 index 0000000..642cd4a --- /dev/null +++ b/extra.py @@ -0,0 +1,222 @@ +from PIL import Image, ImageTk +from PIL import ImageFilter +import tkinter as tk # 导入 Tkinter 库 +from tkinter.filedialog import askopenfilename +import tkinter.messagebox +import tkinter.ttk +import tkinter.messagebox +from PIL import ImageDraw +from PIL import ImageFont +from PIL import ImageEnhance +import numpy as np +import cv2 as cv +import matplotlib.pyplot as plt +from tkinter import simpledialog +import collections +import os + +class wlw(object): + """description of class""" + + # 加了滤镜的拓展功能,用的ImageFilter库 + def blurPic(Imf): + Im2 = Imf.filter(ImageFilter.BLUR) # 图像模糊 + return Im2 + + def edge(Imf): + Im4 = Imf.filter(ImageFilter.EDGE_ENHANCE) # 边界增强 + return Im4 + + def gaussianBlur(Imf): + Im6 = Imf.filter(ImageFilter.GaussianBlur) # 高斯模糊 + return Im6 + + def emboss(Imf): + Im8 = Imf.filter(ImageFilter.EMBOSS) # 浮雕滤镜, + return Im8 + + # 以下为自己编写函数实现的功能 + # 线性灰度转换 + def linearization(Imf, a=1.5, c=1.5): + Im12 = np.array(Imf) + r, g, b = Im12[:, :, 0], Im12[:, :, 1], Im12[:, :, 2] + Im12 = 0.2989 * r + 0.5870 * g + 0.1140 * b + Im12 = float(a) * Im12 + float(c) # 对矩阵类型计算,a是对比度,c是亮度,由k和b传入 + # 进行数据截断,大于255的值要截断为255 + Im12[Im12 > 255] = 255 + # 数据类型转化 + Im12 = np.round(Im12) + Im12 = Im12.astype(np.uint8) + return Image.fromarray(Im12) + + # 非线性log灰度转换 + def tologpic(Imf, c=30.0): + Im14 = np.array(Imf) + r, g, b = Im14[:, :, 0], Im14[:, :, 1], Im14[:, :, 2] + Im14 = 0.2989 * r + 0.5870 * g + 0.1140 * b + Im14 = c * np.log(1.0 + Im14) # 对数运算 + Im14[Im14 > 255] = 255 # 这里应该是不用截断的 + Im14 = np.uint8(Im14 + 0.5) + return Image.fromarray(Im14) + + # n值灰度转换 + def tonpic(Imf, n=1.5): + Im16 = np.array(Imf) # 转换矩阵 + r, g, b = Im16[:, :, 0], Im16[:, :, 1], Im16[:, :, 2] # 灰度变换 + Im16 = 0.2989 * r + 0.5870 * g + 0.1140 * b + Im16 = float(n) * Im16 # 对矩阵类型计算 + # 进行数据截断,大于255的值要截断为255 + Im16[Im16 > 255] = 255 + # 数据类型转化 + Im16 = np.round(Im16) + Im16 = Im16.astype(np.uint8) + return Image.fromarray(Im16) + + # 计算直方图 + def showhist(image): + def clczhifangtu(gray): + # 计算彩色图单通道的直方图 + hist_new = [] + num = [] + hist_result = [] + hist_key = [] + gray1 = list(gray.ravel()) # 将读取出来的数组转化为一维列表方便循环遍历 + obj = dict(collections.Counter(gray1)) # 计算每个灰度级出现的次数 + obj = sorted(obj.items(), key=lambda item: item[0]) + # 初始化hist数组 + for each in obj: + hist1 = [] + key = list(each)[0] + each = list(each)[1] + hist_key.append(key) + hist1.append(each) + hist_new.append(hist1) + # 检查从0-255每个通道是否都有个数,没有的话添加并将值设为0 + for i in range(0, 256): + if i in hist_key: + num = hist_key.index(i) + hist_result.append(hist_new[num]) + else: + hist_result.append([0]) + # 检查循环后的列表中是不是已经包含所有的灰度级 + if len(hist_result) < 256: + for i in range(0, 256 - len(hist_result)): + hist_new.append([0]) + hist_result = np.array(hist_result) + return hist_result + + image = np.array(image) + r, g, b = image[:, :, 0], image[:, :, 1], image[:, :, 2] + + hist_new_b = clczhifangtu(b) + hist_new_g = clczhifangtu(g) + hist_new_r = clczhifangtu(r) + + # 绘制直方图 + plt.plot(hist_new_b, color='b') + plt.plot(hist_new_g, color='g') + plt.plot(hist_new_r, color='r') + plt.show() + + # 图像相加 + def Add(img1, img2): + # 图像相加函数 + def IMG_PLUS(img1, img2): + # 先修改img1尺寸和img2相同 + img1 = cv.resize(img1, (img2.shape[1], img2.shape[0])) + # 矩阵相加 + newimg = img1 * 0.5 + img2 * 0.5 + newimg = newimg.astype(np.uint8) + return newimg + + first = np.array(img1) + second = np.array(img2) + newimg = IMG_PLUS(first, second) + return ImageTk.PhotoImage(Image.fromarray(newimg)) + + # 均值滤波 + def filter1(img): + def filter(img, b=3): + padnum = (b - 1) // 2 # 填充数量 + pad = ((padnum, padnum), (padnum, padnum), (0, 0)) # 填充格式 + Filter = np.ones((b, b, img.shape[2]), img.dtype) # 方阵滤波器 + padnumImg = np.pad(img, pad, 'constant', constant_values=(0, 0)) + # 用滤波器对图像中像素依次计算取均值 + for i in range(padnum, padnumImg.shape[0] - padnum): + for j in range(padnum, padnumImg.shape[1] - padnum): + padnumImg[i][j] = (Filter * padnumImg[i - padnum:i + padnum + 1, j - padnum:j + padnum + 1]).sum( + axis=0).sum(axis=0) // (b ** 2) + newimg = padnumImg[padnum:padnumImg.shape[0] - padnum, padnum:padnumImg.shape[1] - padnum] # 剪切使尺寸一样 + return newimg + + l = simpledialog.askinteger(title='滤波核size', prompt='边长L', initialvalue=3, minvalue=0, maxvalue=99) + img = filter(np.array(img), l) + return ImageTk.PhotoImage(Image.fromarray(img)) + + # 中值滤波 + def filter2(img): + # 中值滤波处理函数 + def filter(img, b=3): + padnum = (b - 1) // 2 # 填充数量 + pad = ((padnum, padnum), (padnum, padnum), (0, 0)) # 填充格式 + padImg = np.pad(img, pad, 'constant', constant_values=(0, 0)) # 方阵滤波器 + + # 按通道计算中值函数 + def DimensionAdd(img): + blank = np.zeros((img.shape[2])) + for i in range(img.shape[2]): + blank[i] = np.median(img[:, :, i]) + return blank + + # 用滤波器对图像中像素依次计算中值 + for i in range(padnum, padImg.shape[0] - padnum): + for j in range(padnum, padImg.shape[1] - padnum): + padImg[i][j] = DimensionAdd(padImg[i - padnum:i + padnum + 1, j - padnum:j + padnum + 1]) + newimg = padImg[padnum:padImg.shape[0] - padnum, padnum:padImg.shape[1] - padnum] # 把操作完多余的0去除,保证尺寸一样大 + return newimg + + l = simpledialog.askinteger(title='滤波核size', prompt='边长L', initialvalue=3, minvalue=0, maxvalue=99) + img = filter(np.array(img), l) + return ImageTk.PhotoImage(Image.fromarray(img)) + + # sobel锐化 + def sharpen(img): + + img = np.array(img) + r, g, b = img[:, :, 0], img[:, :, 1], img[:, :, 2] + img = 0.2989 * r + 0.5870 * g + 0.1140 * b + # sobel算子 + G_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) + G_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]) + rows = np.size(img, 0) + columns = np.size(img, 1) + mag = np.zeros(img.shape) + # 分别检测水平和垂直,在计算每个pixel的时候,将水平和垂直的值作一次平方和的处理 + for i in range(0, rows - 2): + for j in range(0, columns - 2): + v = sum(sum(G_x * img[i:i + 3, j:j + 3])) # vertical + h = sum(sum(G_y * img[i:i + 3, j:j + 3])) # horizon + mag[i + 1, j + 1] = np.sqrt((v ** 2) + (h ** 2)) + # 设置阈值 + threshold = 120 + mag[mag < threshold] = 0 + + mag = mag.astype(np.uint8) + return Image.fromarray(mag) + + # 人脸检测 + def face_detect(img, path): + img = cv.imread(path) + name = path.split('.')[0] + print(img) + if (img.ndim == 3): + gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) + else: + gray = img + face_cas = cv.CascadeClassifier('haarcascade_frontalface_default.xml') + face_scale = face_cas.detectMultiScale(gray, 1.1, 5, 0, (100, 100), (400, 400)) + print(face_scale) + for (x, y, w, h) in face_scale: + cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1) + cv.putText(img, name, (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 1) + return Image.fromarray(img)