diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..0cf5ea5 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": "No Configurations" +} \ No newline at end of file diff --git a/.vs/PythonSettings.json b/.vs/PythonSettings.json new file mode 100644 index 0000000..609cb17 --- /dev/null +++ b/.vs/PythonSettings.json @@ -0,0 +1,4 @@ +{ + "Interpreter": "Workspace|Workspace|env", + "TestFramework": "Pytest" +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..91b266e --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,8 @@ +{ + "ExpandedNodes": [ + "", + "\\__pycache__" + ], + "SelectedNode": "\\ImgProc.py", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/img_proc/FileContentIndex/02e5c044-cfcf-456a-a383-91a2c7547bb4.vsidx b/.vs/img_proc/FileContentIndex/02e5c044-cfcf-456a-a383-91a2c7547bb4.vsidx new file mode 100644 index 0000000..4183918 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/02e5c044-cfcf-456a-a383-91a2c7547bb4.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/08043735-02df-481a-8d19-d290e0338ca8.vsidx b/.vs/img_proc/FileContentIndex/08043735-02df-481a-8d19-d290e0338ca8.vsidx new file mode 100644 index 0000000..a8f2bd2 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/08043735-02df-481a-8d19-d290e0338ca8.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/2338f315-6a86-46da-b731-8b06394d43c9.vsidx b/.vs/img_proc/FileContentIndex/2338f315-6a86-46da-b731-8b06394d43c9.vsidx new file mode 100644 index 0000000..1088e81 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/2338f315-6a86-46da-b731-8b06394d43c9.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/2b79d1a0-5b04-4ec3-9e6a-67d05a5fc0d3.vsidx b/.vs/img_proc/FileContentIndex/2b79d1a0-5b04-4ec3-9e6a-67d05a5fc0d3.vsidx new file mode 100644 index 0000000..627c8a1 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/2b79d1a0-5b04-4ec3-9e6a-67d05a5fc0d3.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/3752881c-efd7-4d27-99e8-f033529a956c.vsidx b/.vs/img_proc/FileContentIndex/3752881c-efd7-4d27-99e8-f033529a956c.vsidx new file mode 100644 index 0000000..55ec384 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/3752881c-efd7-4d27-99e8-f033529a956c.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/4f6c53a1-62ba-4285-9657-2f33ec2243ae.vsidx b/.vs/img_proc/FileContentIndex/4f6c53a1-62ba-4285-9657-2f33ec2243ae.vsidx new file mode 100644 index 0000000..0559e34 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/4f6c53a1-62ba-4285-9657-2f33ec2243ae.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/5f9bd2ba-eff7-4a37-9c6b-c59de2b1477a.vsidx b/.vs/img_proc/FileContentIndex/5f9bd2ba-eff7-4a37-9c6b-c59de2b1477a.vsidx new file mode 100644 index 0000000..b9d15f7 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/5f9bd2ba-eff7-4a37-9c6b-c59de2b1477a.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/66e671da-79b6-4cb0-af13-a37259201e20.vsidx b/.vs/img_proc/FileContentIndex/66e671da-79b6-4cb0-af13-a37259201e20.vsidx new file mode 100644 index 0000000..0416a73 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/66e671da-79b6-4cb0-af13-a37259201e20.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/d5e13469-a6dc-4fc2-9734-8487cf6e4f05.vsidx b/.vs/img_proc/FileContentIndex/d5e13469-a6dc-4fc2-9734-8487cf6e4f05.vsidx new file mode 100644 index 0000000..09dc079 Binary files /dev/null and b/.vs/img_proc/FileContentIndex/d5e13469-a6dc-4fc2-9734-8487cf6e4f05.vsidx differ diff --git a/.vs/img_proc/FileContentIndex/read.lock b/.vs/img_proc/FileContentIndex/read.lock new file mode 100644 index 0000000..e69de29 diff --git a/.vs/img_proc/v17/.suo b/.vs/img_proc/v17/.suo new file mode 100644 index 0000000..040fbeb Binary files /dev/null and b/.vs/img_proc/v17/.suo differ diff --git a/.vs/img_proc/v17/Browse.VC.db b/.vs/img_proc/v17/Browse.VC.db new file mode 100644 index 0000000..783ddbe Binary files /dev/null and b/.vs/img_proc/v17/Browse.VC.db differ diff --git a/.vs/img_proc/v17/Browse.VC.db-shm b/.vs/img_proc/v17/Browse.VC.db-shm new file mode 100644 index 0000000..007401b Binary files /dev/null and b/.vs/img_proc/v17/Browse.VC.db-shm differ diff --git a/.vs/img_proc/v17/Browse.VC.db-wal b/.vs/img_proc/v17/Browse.VC.db-wal new file mode 100644 index 0000000..e69de29 diff --git a/.vs/img_proc/v17/Browse.VC.opendb b/.vs/img_proc/v17/Browse.VC.opendb new file mode 100644 index 0000000..c3fa2b6 Binary files /dev/null and b/.vs/img_proc/v17/Browse.VC.opendb differ diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..98d865b Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/ImgProc.py b/ImgProc.py new file mode 100644 index 0000000..562a12d --- /dev/null +++ b/ImgProc.py @@ -0,0 +1,1002 @@ +from PIL import Image +from PIL import ImageTk +from PIL import ImageFilter +from PIL import ImageEnhance + +import tkinter as tk # Tkinter: python内置GUI +from tkinter.filedialog import askopenfilename +import tkinter.ttk +import tkinter.messagebox +from tkinter import simpledialog + +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.optim as optim +import torchvision.transforms as transforms +import torchvision.models as models + +import numpy as np +import cv2 as cv +import matplotlib.pyplot as plt +import collections + +#import os +#os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" + +class picture(object): + """description of class""" + # 打开图像调用 + def open_pic(self, address): + self.pic_get = Image.open(address).convert('RGBA') + wid, hei = self.pic_get.size + if wid > 600 or hei > 400: + if tk.messagebox.askokcancel('提示', '图片可能过大,是否压缩?'): + needShow_pic = self.openResize() + return needShow_pic + return self.pic_get + else: + return self.pic_get + + # 打开图像时的图像压缩展示 + def openResize(self): + w, h = self.pic_get.size + w_hope = 500 + h_hope = 300 + f1 = 1.0 * w_hope / w + f2 = 1.0 * h_hope / h + factor = min([f1, f2]) + width = int(w * factor) + height = int(h * factor) + pic_show = self.pic_get.resize((width, height)) + return pic_show + +# 截图处理 + def Cutpic(self, pic_preCut, p1, p2, p3, p4): + cropped_pic = pic_preCut.crop((p1, p2, p3, p4))#截图 + return cropped_pic + +# 尺寸大小变化 + def changeResize(self, pic_reshow, newWidth, newHeight): + reesizeNew_pic = pic_reshow.resize((newWidth, newHeight))#修改尺寸 + # print('3') + return reesizeNew_pic + + +# 镜像左右 + def MirrorPic_leftOrright(self, pic_mir_lr): + Mirror_lrFinish = pic_mir_lr.transpose(Image.Transpose.FLIP_LEFT_RIGHT)# 镜像左右 + return Mirror_lrFinish + +# 镜像上下 + def MirrorPic_topOrbuttom(self, pic_mir_tp): + Mirror_tbFinish = pic_mir_tp.transpose(Image.Transpose.FLIP_LEFT_RIGHT)# 镜像上下 + return Mirror_tbFinish +# 旋转 + def rotatePic(self, pic_prerotate, rodegreee): + rotateNew_pic = pic_prerotate.rotate(rodegreee, expand=True) + return rotateNew_pic +# 亮度 + def brightPic(self, pic_prebright, n): + pic_brighted = ImageEnhance.Brightness(pic_prebright).enhance(n)# 亮度 + return pic_brighted + +# 色彩度 + def colornPic(self, pic_preColor, n): + pic_colored = ImageEnhance.Color(pic_preColor).enhance(n)# 色彩度 + return pic_colored + +# 对比度 + def constractPic(self, pic_preCon, n): + enh_con = ImageEnhance.Contrast(pic_preCon) + contrast = n + pic_contrasted = enh_con.enhance(contrast)# 对比度 + return pic_contrasted + +# 锐度调整 + def sharpPic(self, pic_preSharp, n): + pic_sharped = ImageEnhance.Sharpness(pic_preSharp).enhance(n) + return pic_sharped + + +class modules(object): + + def forward(self, img): + # normalize img + return (img - self.mean) / self.std + + + """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, c): + 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): + 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): + 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 + + Im16[Im16>255]=255 + # 数据类型转化 + Im16=np.round(Im16) + Im16=Im16.astype(np.uint8) + return Image.fromarray(Im16) + + def calc_hist(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] + cnt = list(each)[1] + hist_key.append(key) + hist1.append(cnt) + 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]) + hist_result = np.array(hist_result) + return hist_result + + # 计算直方图 + def showhist(image): + image= np.array(image) + r,g,b = image[:,:,0], image[:,:,1], image[:,:,2] + + hist_new_b = modules.calc_hist(b) + hist_new_g = modules.calc_hist(g) + hist_new_r = modules.calc_hist(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 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 + + # 图像相加 + def Add(img1, img2): + first = np.array(img1) + second = np.array(img2) + newimg = modules.IMG_PLUS(first, second) + #return ImageTk.PhotoImage(Image.fromarray(newimg)) + return Image.fromarray(newimg) + + # 均值滤波处理函数 + def mean_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 + + # 中值滤波处理函数 + def median_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 + + # 均值滤波 + def filter1(img): + l = simpledialog.askinteger(title='滤波核size', prompt='边长L', initialvalue=3, minvalue=0, maxvalue=99) + img = modules.mean_filter(np.array(img), l) + return ImageTk.PhotoImage(Image.fromarray(img)) + + # 中值滤波 + def filter2(img): + l = simpledialog.askinteger(title='滤波核size', prompt='边长L', initialvalue=3, minvalue=0, maxvalue=99) + img = modules.median_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