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.

613 lines
25 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import *
from tkinter.colorchooser import *
import numpy as np
import cv2
import cv2 as cv
import sys
from PIL import Image, ImageTk
import matplotlib.pyplot
import matplotlib.pyplot as plt
from PIL.Image import Resampling
global out_path
out_path="img/output/test.png"
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.textpad = None
self.place()
self.createWidget()
def test(self):
pass
def createWidget(self):
menubar = Menu(root)
menuFile = Menu(menubar)
menuNoise = Menu(menubar)
menuDetect = Menu(menubar)
menuBinary = Menu(menubar)
空域的平滑 = Menu(menubar)
频域的平滑 = Menu(menubar)
数字图像直方图 = Menu(menubar)
menubar.add_cascade(label="文件", menu=menuFile)
menubar.add_cascade(label="线条变化检测与边缘检测", menu=menuDetect)
menubar.add_cascade(label="噪声滤除", menu=menuNoise)
menubar.add_cascade(label="数字图像形态学", menu=menuBinary)
menubar.add_cascade(label="空域的平滑", menu=空域的平滑)
menubar.add_cascade(label="频域的平滑", menu=频域的平滑)
menubar.add_cascade(label="数字图像直方图", menu=数字图像直方图)
menuFile.add_command(label="打开", command=self.openfile)
menuFile.add_command(label="保存", command=self.savefile)
menuDetect.add_command(label="线条变化检测", command=self.线条变化检测)
menuDetect.add_command(label="边缘检测的基本原理和图像增强", command=self.边缘检测的基本原理和图像增强)
menuDetect.add_command(label="Roberts算子", command=self.Roberts算子)
menuDetect.add_command(label="Prewitt算子与Sobel算子", command=self.Prewitt算子与Sobel算子)
menuDetect.add_command(label="Laplacian算子", command=self.Laplacian算子)
menuDetect.add_command(label="LoG边缘算子", command=self.LoG边缘算子)
menuDetect.add_command(label="Canny边缘检测", command=self.Canny边缘检测)
menuNoise.add_command(label="噪声描述器", command=self.噪声描述器)
menuNoise.add_command(label="均值类滤波器", command=self.均值类滤波器)
menuNoise.add_command(label="排序统计类滤波器", command=self.排序统计类滤波器)
menuNoise.add_command(label="选择性滤波器", command=self.选择性滤波器)
menuBinary.add_command(label="腐蚀", command=self.腐蚀)
menuBinary.add_command(label="膨胀", command=self.膨胀)
menuBinary.add_command(label="开运算", command=self.开运算)
menuBinary.add_command(label="闭运算", command=self.闭运算)
频域的平滑.add_command(label="理想低通滤波", command=self.理想低通滤波)
频域的平滑.add_command(label="巴特沃斯低通滤波", command=self.巴特沃斯低通滤波)
频域的平滑.add_command(label="高斯低通滤波", command=self.高斯低通滤波)
空域的平滑.add_command(label="均值滤波", command=self.均值滤波)
空域的平滑.add_command(label="中值滤波", command=self.中值滤波)
数字图像直方图.add_command(label="灰度直方图", command=self.灰度直方图)
数字图像直方图.add_command(label="彩色直方图", command=self.彩色直方图)
数字图像直方图.add_command(label="绘制直方图", command=self.绘制直方图)
数字图像直方图.add_command(label="分段线性变换对直方图修改", command=self.分段线性变换对直方图修改)
root["menu"] = menubar
self.original_label = Label(text="原始图片")
self.original_label.place(x=50, y=50)
self.edited_label = Label(text="处理后的图片")
self.edited_label.place(x=550, y=50)
global original_canvas # 展示原始图片的画布
self.original_canvas = Canvas(width=500, height=500, bg='blue', bd=0)
self.original_canvas.place(x=50, y=100)
global edited_canvas # 展示处理后的图片的画布
self.edited_canvas = Canvas(width=500, height=500, bg='blue', bd=0)
self.edited_canvas.place(x=550, y=100)
def img_resize(self, image):
"""在APP页面展示图片需要调整图片大小使图片按照原比例放在画布组件内"""
w, h = image.size
if h > w:
target_size = (int(500*(w/h)), 500)
else:
target_size = (500, int(500*(h/w)))
scale_img = image.copy()
out = scale_img.resize(target_size, Resampling.LANCZOS)
return out
def openfile(self):
"""
使用askopenfile获取文件路径在canvas中展示使用Image.open和ImageTk.PhotoImage打开
而在opencv处理图片时使用cv2.imwrite(path)直接打开图片
"""
with askopenfile(title="打开图片") as f:
global img_1, img_2
global path
path = f.name
img_1 = Image.open(path)
img_2 = self.img_resize(img_1)
original_img = ImageTk.PhotoImage(img_2)
self.original_canvas.create_image(251, 253, image=original_img)
self.original_canvas.image = original_img
self.edited_canvas.delete("all")
root.update()
def savefile(self):
"""
使用asksaveasfilename获取文件名使用image.save进行保存
这样做的好处是:可以自定义储存的文件名以及后缀,避免固定文件
名带来后续保存覆盖之前的保存的问题
"""
out_path = asksaveasfilename(title="保存图片")
cv2.imwrite(out_path, output)
def get_max(self, arr):
# 列表的长度
length = len(arr)
# 对列表进行选择排序,获得有序的列表
for i in range(length):
for j in range(i + 1, length):
# 选择最大的值
if arr[j] > arr[i]:
# 交换位置
temp = arr[j]
arr[j] = arr[i]
arr[i] = temp
return arr[0]
def 噪声描述器(self):
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
global output
output = np.zeros(image.shape, np.uint8)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
# 添加食盐噪声
if image[i][j] < 100:
output[i][j] = 255
# 添加胡椒噪声
elif image[i][j] > 200:
output[i][j] = 0
# 不添加噪声
else:
output[i][j] = image[i][j]
img_1 = Image.fromarray(np.uint8(output))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 均值类滤波器(self):
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
global output
output = np.zeros(image.shape, np.uint8)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
ji = 1.0
for m in range(-1, 2):
if 0 <= j + m < image.shape[1]:
ji *= image[i][j + m]
output[i][j] = ji ** (1 / 3)
img_1 = Image.fromarray(np.uint8(output))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 排序统计类滤波器(self):
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
array = []
global output
output = np.zeros(image.shape, np.uint8)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
# 最大值滤波器
array.clear()
for m in range(-1, 2):
for n in range(-1, 2):
if 0 <= i + m < image.shape[0] and 0 <= j + n < image.shape[1]:
array.append(image[i + m][j + n])
output[i][j] = self.get_max(arr=array)
img_1 = Image.fromarray(np.uint8(output))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 选择性滤波器(self):
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
global output
output = np.zeros(image.shape, np.uint8)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i][j] > 200:
output[i][j] = image[i][j]
else:
output[i][j] = 0
img_1 = Image.fromarray(np.uint8(output))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 线条变化检测(self):
img = cv2.imread(path)
img = cv2.GaussianBlur(img, (3, 3), 0)
edges = cv2.Canny(img, 50, 150, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi / 2, 118)
result = img.copy()
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 - result.shape[0] * np.sin(theta)) / np.cos(theta)), result.shape[0])
cv2.line(result, pt1, pt2, (0, 0, 255))
else:
pt1 = (0, int(rho / np.sin(theta)))
pt2 = (result.shape[1], int((rho - result.shape[1] * np.cos(theta)) / np.sin(theta)))
cv2.line(result, pt1, pt2, (0, 0, 255), 1)
minLineLength = 200
maxLineGap = 15
linesP = cv2.HoughLinesP(edges, 1, np.pi / 180, 80, minLineLength, maxLineGap)
result_P = img.copy()
for i_P in linesP:
for x1, y1, x2, y2 in i_P:
cv2.line(result_P, (x1, y1), (x2, y2), (0, 255, 0), 3)
global output
output = result_P
img_1 = Image.fromarray(np.uint8(result_P))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 边缘检测的基本原理和图像增强(self):
CRH = cv2.imread(path, 0)
CRH = CRH.astype('float')
h, w = CRH.shape
gradient = np.zeros((h, w))
gradient = gradient.astype('float')
for x in range(h - 1):
for y in range(w - 1):
gx = abs(CRH[x + 1, y] - CRH[x, y])
gy = abs(CRH[x, y + 1] - CRH[x, y])
gradient[x, y] = gx + gy
sharp = CRH + gradient
sharp = np.where(sharp > 255, 255, sharp)
sharp = np.where(sharp < 0, 0, sharp)
gradient = gradient.astype('uint8')
sharp = sharp.astype('uint8')
global output
output = gradient
img_1 = Image.fromarray(np.uint8(gradient))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def Roberts算子(self):
img = cv2.imread(path)
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
kernely = np.array([[0, -1], [1, 0]], dtype=int)
x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
global output
output = Roberts
img_1 = Image.fromarray(np.uint8(Roberts))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def Prewitt算子与Sobel算子(self):
img = cv2.imread(path)
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernelx = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0)
kernely = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1)
x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx)
y = cv2.filter2D(grayImage, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
global output
output = Sobel
img_1 = Image.fromarray(np.uint8(Sobel))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def Laplacian算子(self):
img = cv2.imread(path)
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gaussianBlur = cv2.GaussianBlur(grayImage, (5, 5), 0)
dst = cv2.Laplacian(img_gaussianBlur, cv2.CV_16S, ksize=3)
Laplacian = cv2.convertScaleAbs(dst)
global output
output = Laplacian
img_1 = Image.fromarray(np.uint8(Laplacian))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def LoG边缘算子(self):
img = cv2.imread(path)
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])
global output
output = image1
img_1 = Image.fromarray(np.uint8(image1))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def Canny边缘检测(self):
src = cv2.imread(path)
blur = cv2.GaussianBlur(src, (3, 3), 0)
grayImage = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
gradx = cv2.Sobel(grayImage, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(grayImage, cv2.CV_16SC1, 0, 1)
edge_output = cv2.Canny(gradx, grady, 50, 150)
global output
output = edge_output
img_1 = Image.fromarray(np.uint8(edge_output))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 腐蚀(self):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
erosion = cv2.erode(src, kernel)
global output
output = erosion
img_1 = Image.fromarray(np.uint8(erosion))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 膨胀(self):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
dilation = cv2.dilate(src, kernel)
global output
output = dilation
img_1 = Image.fromarray(np.uint8(dilation))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 开运算(self):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
open = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
global output
output = open
img_1 = Image.fromarray(np.uint8(open))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 闭运算(self):
src = cv2.imread(path, cv2.IMREAD_UNCHANGED)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (10, 10))
close = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)
global output
output = close
img_1 = Image.fromarray(np.uint8(close))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 理想低通滤波(self):
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img = np.float32(img)
dft = cv2.dft(img, flags=cv2.DFT_COMPLEX_OUTPUT)
dft = np.fft.fftshift(dft)
rows, cols = img.shape
mask = np.zeros((rows, cols, 2))
mask[int(rows / 2) - 20:int(rows / 2) + 20, int(cols / 2) - 20:int(cols / 2) + 20] = 1
f = dft * mask
f = np.fft.ifftshift(f)
img = cv2.idft(f)
img = cv2.magnitude(img[:, :, 0], img[:, :, 1])
global output
output = img
img_1 = Image.fromarray(np.uint8(img))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 巴特沃斯低通滤波(self):
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img = np.float32(img)
dft = cv2.dft(img, flags=cv2.DFT_COMPLEX_OUTPUT)
dft = np.fft.fftshift(dft)
rows, cols = img.shape
mask = np.zeros((rows, cols, 2))
D0 = 20
N = 2
for i in range(rows):
for j in range(cols):
D = np.sqrt((i - rows / 2) ** 2 + (j - cols / 2) ** 2)
mask[i, j, 0] = mask[i, j, 1] = 1.0 / (1.0 + ((D / D0) ** (2 * N)))
f = dft * mask
f = np.fft.ifftshift(f)
img = cv2.idft(f)
img = cv2.magnitude(img[:, :, 0], img[:, :, 1])
global output
output = img
img_1 = Image.fromarray(np.uint8(img))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 高斯低通滤波(self):
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img = np.float32(img)
dft = cv2.dft(img, flags=cv2.DFT_COMPLEX_OUTPUT)
dft = np.fft.fftshift(dft)
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)
mask = np.zeros((rows, cols, 2))
D0 = 20
for i in range(rows):
for j in range(cols):
D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)
mask[i, j, 0] = mask[i, j, 1] = np.exp(-(D * D) / (2 * D0 * D0))
f = dft * mask
f = np.fft.ifftshift(f)
img = cv2.idft(f)
img = cv2.magnitude(img[:, :, 0], img[:, :, 1])
global output
output = img
img_1 = Image.fromarray(np.uint8(img))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 中值滤波(self):
img = cv2.imread(path)
mid_blur = cv2.medianBlur(img, 3)
global output
output = mid_blur
img_1 = Image.fromarray(np.uint8(mid_blur))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 均值滤波(self):
img = cv2.imread(path)
avg_blur = cv2.blur(img, (3, 3))
global output
output = avg_blur
img_1 = Image.fromarray(np.uint8(avg_blur))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
def 灰度直方图(self):
fileName = 'img/output/灰度直方图的计算-默认输出.png'
img = cv.imread(path, 0)
plt.figure(fileName, figsize=(16, 8))
plt.subplot(121)
plt.imshow(img, "gray")
plt.subplot(122)
hist = cv.calcHist([img], [0], None, [256], [0, 255])
plt.plot(hist)
plt.xlim([0, 255])
img_1 = Image.fromarray(np.uint8(img))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
plt.savefig(fileName)
plt.show()
def 彩色直方图(self):
imgOri1 = cv2.imread(path)
fileName = 'img/output/彩色直方图的计算-默认输出.png'
color = ["r", "g", "b"]
img_rgb2 = cv2.cvtColor(imgOri1, cv2.COLOR_BGR2RGB)
plt.subplot(121)
plt.imshow(imgOri1)
plt.subplot(122)
for index, c in enumerate(color):
hist = cv2.calcHist([img_rgb2], [index], None, [256], [0, 255])
plt.plot(hist, color=c)
plt.xlim([0, 255])
img_1 = Image.fromarray(np.uint8(img_rgb2))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
plt.savefig(fileName)
plt.show()
def 绘制直方图(self):
img = cv2.imread(path)
b, g, r = cv2.split(img)
hist = cv2.calcHist([b], [0], None, [256], [0, 256])
plt.plot(hist, color='blue')
plt.xlim([0, 256])
hist = cv2.calcHist([g], [0], None, [256], [0, 256])
plt.plot(hist, color='green')
plt.xlim([0, 256])
hist = cv2.calcHist([r], [0], None, [256], [0, 256])
plt.plot(hist, color='red')
plt.xlim([0, 256])
img_1 = Image.fromarray(np.uint8(img))
img_2 = self.img_resize(img_1)
edited_img = ImageTk.PhotoImage(img_2)
self.edited_canvas.create_image(253, 253, image=edited_img)
self.edited_canvas.image = edited_img
plt.savefig('img/output/绘制直方图-默认输出')
def grayHist(self, img, filename):
plt.figure(filename, figsize=(16, 8))
plt.subplot(121)
plt.imshow(img, 'gray')
plt.subplot(122)
h, w = img.shape[:2]
pixelSequence = img.reshape(1, -1)
numberBins = 256
histogram, bins, patch = plt.hist(img.ravel(), 256, range=[0, 256])
print(max(histogram))
plt.xlabel("gray label")
plt.ylabel("number of pixels")
plt.axis([0, 255, 0, np.max(histogram)])
plt.savefig(filename)
plt.show()
def 分段线性变换对直方图修改(self):
img_path = path
out_path = 'img/output/分段线性变换_1'
out2_path = 'img/output/分段线性变换_2'
img = cv2.imread(img_path, 0)
h, w = img.shape[:2]
out = np.zeros(img.shape, np.uint8)
for i in range(h):
for j in range(w):
if img[i][j] < 50:
out[i][j] = 0.5 * img[i][j]
elif img[i][j] < 150:
out[i][j] = 3.6 * img[i][j] - 310
else:
out[i][j] = 0.238 * img[i][j] + 194
out = np.around(out)
out = out.astype(np.uint8)
self.grayHist(img, out_path)
self.grayHist(out, out2_path)
if __name__ == '__main__':
root = Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
root.geometry(f"1100x700+{int(0.5*(screen_width-1100))}+{int(0.5*(screen_height-700))}") #居中窗口
root.resizable(width=False, height=False)
root.title("数字图像处理")
app = Application(master=root)
root.mainloop()