diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..359bb53
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..8086a31
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,13 @@
+
+  
+    
+    
+      
+    
+  
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+  
+    
+    
+  
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..d56657a
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..2aed417
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+  
+    
+      
+    
+  
+
\ No newline at end of file
diff --git a/.idea/opencv-pyqt5-master.iml b/.idea/opencv-pyqt5-master.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/opencv-pyqt5-master.iml
@@ -0,0 +1,8 @@
+
+
+  
+    
+    
+    
+  
+
\ No newline at end of file
diff --git a/__pycache__/config.cpython-39.pyc b/__pycache__/config.cpython-39.pyc
new file mode 100644
index 0000000..942390a
Binary files /dev/null and b/__pycache__/config.cpython-39.pyc differ
diff --git a/__pycache__/flags.cpython-39.pyc b/__pycache__/flags.cpython-39.pyc
new file mode 100644
index 0000000..af50902
Binary files /dev/null and b/__pycache__/flags.cpython-39.pyc differ
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..3f4fd46
--- /dev/null
+++ b/config.py
@@ -0,0 +1,108 @@
+from custom.tableWidget import *
+from custom.listWidgetItems import *
+
+
+# Implemented functions
+items = [
+    GrayingItem,
+    FilterItem,
+    EqualizeItem,
+    MorphItem,
+    GradItem,
+    ThresholdItem,
+    EdgeItem,
+    ContourItem,
+    HoughLineItem,
+    GammaItem
+
+]
+
+items1 = [
+    ImageCutItem,
+    RotateAnyItem,
+    RotateLeftItem,
+    RotateRightItem,
+    UpDownItem
+]
+
+items2 = [
+    ExposureItem,
+    ContrastItem,
+    LightItem
+]
+
+items3 = [
+    ColorTemperatureItem,
+    HueItem,
+    SaturationItem
+]
+
+items4 = [
+    HSLRedItem,
+    HSLOrangeItem,
+    HSLYellowItem,
+    HSLGreenItem,
+    HSLCyanItem,
+    HSLBlueItem,
+    HSLPurpleItem
+]
+
+items5 = [
+    PixelateItem,
+    BlurItem
+
+]
+
+items6 = [
+    CandyStyleTransformItem,
+    CompositionStyleTransformItem,
+    FeathersStyleTransformItem,
+    MuseStyleTransformItem,
+    MosaicStyleTransformItem,
+    StarryNightStyleTransformItem,
+    ScreamStyleTransformItem,
+    WaveStyleTransformItem,
+    UdnieStyleTransformItem
+]
+
+items7 = [
+    ClarityItem,
+    NoiseItem
+]
+
+tables = [
+    GrayingTableWidget,
+    FilterTabledWidget,
+    EqualizeTableWidget,
+    MorphTabledWidget,
+    GradTabledWidget,
+    ThresholdTableWidget,
+    EdgeTableWidget,
+    ContourTableWidget,
+    HoughLineTableWidget,
+    GammaITabelWidget,
+    ImageCutTableWidget,
+    RotateAnyTabelWidget,
+    RotateLeftTableWidget,
+    RotateRightTableWidget,
+    UpDownTableWidget,
+    ExposureTabelWidget,
+    ContrastTabelWidget,
+    LightTableWidget,
+    ColorTemperatureTabelWidget,
+    HueTabelWidget,
+    SaturationTabelWidget,
+    HSLRedWidget,
+    HSLOrangeWidget,
+    HSLYellowWidget,
+    HSLGreenWidget,
+    HSLCyanWidget,
+    HSLBlueWidget,
+    HSLPurpleWidget,
+    PixelateTabelWidget,
+    BlurTabelWidget,
+    StyleTransformTableWidget,
+
+
+]
+
diff --git a/custom/__pycache__/graphicsView.cpython-39.pyc b/custom/__pycache__/graphicsView.cpython-39.pyc
new file mode 100644
index 0000000..fcf1987
Binary files /dev/null and b/custom/__pycache__/graphicsView.cpython-39.pyc differ
diff --git a/custom/__pycache__/listWidgetItems.cpython-39.pyc b/custom/__pycache__/listWidgetItems.cpython-39.pyc
new file mode 100644
index 0000000..89d9f45
Binary files /dev/null and b/custom/__pycache__/listWidgetItems.cpython-39.pyc differ
diff --git a/custom/__pycache__/listWidgets.cpython-39.pyc b/custom/__pycache__/listWidgets.cpython-39.pyc
new file mode 100644
index 0000000..69b299f
Binary files /dev/null and b/custom/__pycache__/listWidgets.cpython-39.pyc differ
diff --git a/custom/__pycache__/stackedWidget.cpython-39.pyc b/custom/__pycache__/stackedWidget.cpython-39.pyc
new file mode 100644
index 0000000..5ee985b
Binary files /dev/null and b/custom/__pycache__/stackedWidget.cpython-39.pyc differ
diff --git a/custom/__pycache__/tableWidget.cpython-39.pyc b/custom/__pycache__/tableWidget.cpython-39.pyc
new file mode 100644
index 0000000..a704510
Binary files /dev/null and b/custom/__pycache__/tableWidget.cpython-39.pyc differ
diff --git a/custom/__pycache__/treeView.cpython-39.pyc b/custom/__pycache__/treeView.cpython-39.pyc
new file mode 100644
index 0000000..a616e5c
Binary files /dev/null and b/custom/__pycache__/treeView.cpython-39.pyc differ
diff --git a/custom/__pycache__/treeWidgets.cpython-39.pyc b/custom/__pycache__/treeWidgets.cpython-39.pyc
new file mode 100644
index 0000000..8042b33
Binary files /dev/null and b/custom/__pycache__/treeWidgets.cpython-39.pyc differ
diff --git a/custom/graphicsView.py b/custom/graphicsView.py
new file mode 100644
index 0000000..cbdaf35
--- /dev/null
+++ b/custom/graphicsView.py
@@ -0,0 +1,87 @@
+import cv2
+
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+
+
+class GraphicsView(QGraphicsView):
+    def __init__(self, parent=None):
+        super(GraphicsView, self).__init__(parent=parent)
+        self._zoom = 0
+        self._empty = True
+        self._photo = QGraphicsPixmapItem()  # 创建pixmapItem对象用于显示图像
+        self._scene = QGraphicsScene(self)  # 创建存储图元的容器
+        self._scene.addItem(self._photo)
+        self.setScene(self._scene)
+        self.setAlignment(Qt.AlignCenter)  # 居中显示
+        self.setDragMode(QGraphicsView.ScrollHandDrag)  # 设置拖动
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+        self.setMinimumSize(640, 480)
+
+    def contextMenuEvent(self, event):
+        if not self.has_photo():
+            return
+        menu = QMenu()
+        save_action = QAction('另存为', self)
+        save_action.triggered.connect(self.save_current)  # 传递额外值
+        menu.addAction(save_action)
+        menu.exec(QCursor.pos())
+
+    def save_current(self):
+        file_name = QFileDialog.getSaveFileName(self, '另存为', './',
+                                                'Image files(*.jpg *.gif *.png)')[0]
+        print(file_name)
+        if file_name:
+            self._photo.pixmap().save(file_name)
+
+    def get_image(self):
+        if self.has_photo():
+            return self._photo.pixmap().toImage()  # 获取
+
+    def has_photo(self):
+        return not self._empty
+
+    def img_to_pixmap(self, img):
+        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # bgr -> rgb
+        h, w, c = img.shape  # 获取图片形状
+        image = QImage(img, w, h, 3 * w, QImage.Format_RGB888)
+        return QPixmap.fromImage(image)
+
+    def update_image(self, img):
+        self._empty = False
+        self._photo.setPixmap(self.img_to_pixmap(img))
+
+    def change_image(self, img):
+        self.update_image(img)
+        self.fitInView()
+
+    def fitInView(self, scale=True):
+        rect = QRectF(self._photo.pixmap().rect())
+        if not rect.isNull():
+            self.setSceneRect(rect)
+            if self.has_photo():
+                unity = self.transform().mapRect(QRectF(0, 0, 1, 1))
+                self.scale(1 / unity.width(), 1 / unity.height())
+                viewrect = self.viewport().rect()
+                scenerect = self.transform().mapRect(rect)
+                factor = min(viewrect.width() / scenerect.width(),
+                             viewrect.height() / scenerect.height())
+                self.scale(factor, factor)
+            self._zoom = 0
+
+    def wheelEvent(self, event):
+        if self.has_photo():
+            if event.angleDelta().y() > 0:
+                factor = 1.25
+                self._zoom += 1
+            else:
+                factor = 0.8
+                self._zoom -= 1
+            if self._zoom > 0:
+                self.scale(factor, factor)
+            elif self._zoom == 0:
+                self.fitInView()
+            else:
+                self._zoom = 0
diff --git a/custom/listWidgetItems.py b/custom/listWidgetItems.py
new file mode 100644
index 0000000..b148711
--- /dev/null
+++ b/custom/listWidgetItems.py
@@ -0,0 +1,912 @@
+import numpy as np
+import imutils
+from PyQt5.QtCore import QSize
+from PyQt5.QtGui import QIcon, QColor
+from PyQt5.QtWidgets import QListWidgetItem, QPushButton
+from flags import *
+import cv2
+import random
+from PIL import Image
+
+
+class MyItem(QListWidgetItem):
+    def __init__(self, name=None, parent=None):
+        super(MyItem, self).__init__(name, parent=parent)
+        self.setIcon(QIcon('icons/color.png'))
+        self.setSizeHint(QSize(60, 60))  # size
+
+    def get_params(self):
+        protected = [v for v in dir(self) if v.startswith('_') and not v.startswith('__')]
+        param = {}
+        for v in protected:
+            param[v.replace('_', '', 1)] = self.__getattribute__(v)
+        return param
+
+    def update_params(self, param):
+        for k, v in param.items():
+            if '_' + k in dir(self):
+                self.__setattr__('_' + k, v)
+
+
+class GrayingItem(MyItem):
+    def __init__(self, parent=None):
+        super(GrayingItem, self).__init__(' 灰度化 ', parent=parent)
+        self._mode = BGR2GRAY_COLOR
+
+    def __call__(self, img):
+        img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
+        return img
+
+
+class FilterItem(MyItem):
+
+    def __init__(self, parent=None):
+        super().__init__('平滑处理', parent=parent)
+        self._ksize = 3
+        self._kind = MEAN_FILTER
+        self._sigmax = 0
+
+    def __call__(self, img):
+        if self._kind == MEAN_FILTER:
+            img = cv2.blur(img, (self._ksize, self._ksize))
+        elif self._kind == GAUSSIAN_FILTER:
+            img = cv2.GaussianBlur(img, (self._ksize, self._ksize), self._sigmax)
+        elif self._kind == MEDIAN_FILTER:
+            img = cv2.medianBlur(img, self._ksize)
+        return img
+
+
+class MorphItem(MyItem):
+    def __init__(self, parent=None):
+        super().__init__(' 形态学 ', parent=parent)
+        self._ksize = 3
+        self._op = ERODE_MORPH_OP
+        self._kshape = RECT_MORPH_SHAPE
+
+    def __call__(self, img):
+        op = MORPH_OP[self._op]
+        kshape = MORPH_SHAPE[self._kshape]
+        kernal = cv2.getStructuringElement(kshape, (self._ksize, self._ksize))
+        img = cv2.morphologyEx(img, self._op, kernal)
+        return img
+
+
+class GradItem(MyItem):
+
+    def __init__(self, parent=None):
+        super().__init__('图像梯度', parent=parent)
+        self._kind = SOBEL_GRAD
+        self._ksize = 3
+        self._dx = 1
+        self._dy = 0
+
+    def __call__(self, img):
+        if self._dx == 0 and self._dy == 0 and self._kind != LAPLACIAN_GRAD:
+            self.setBackground(QColor(255, 0, 0))
+            self.setText('图像梯度 (无效: dx与dy不同时为0)')
+        else:
+            self.setBackground(QColor(200, 200, 200))
+            self.setText('图像梯度')
+            if self._kind == SOBEL_GRAD:
+                img = cv2.Sobel(img, -1, self._dx, self._dy, self._ksize)
+            elif self._kind == SCHARR_GRAD:
+                img = cv2.Scharr(img, -1, self._dx, self._dy)
+            elif self._kind == LAPLACIAN_GRAD:
+                img = cv2.Laplacian(img, -1)
+        return img
+
+
+class ThresholdItem(MyItem):
+    def __init__(self, parent=None):
+        super().__init__('阈值处理', parent=parent)
+        self._thresh = 127
+        self._maxval = 255
+        self._method = BINARY_THRESH_METHOD
+
+    def __call__(self, img):
+        method = THRESH_METHOD[self._method]
+        img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+        img = cv2.threshold(img, self._thresh, self._thresh, method)[1]
+        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
+        return img
+
+
+class EdgeItem(MyItem):
+    def __init__(self, parent=None):
+        super(EdgeItem, self).__init__('边缘检测', parent=parent)
+        self._thresh1 = 20
+        self._thresh2 = 100
+
+    def __call__(self, img):
+        img = cv2.Canny(img, threshold1=self._thresh1, threshold2=self._thresh2)
+        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
+        return img
+
+
+class ContourItem(MyItem):
+    def __init__(self, parent=None):
+        super(ContourItem, self).__init__('轮廓检测', parent=parent)
+        self._mode = TREE_CONTOUR_MODE
+        self._method = SIMPLE_CONTOUR_METHOD
+        self._bbox = NORMAL_CONTOUR
+
+    def __call__(self, img):
+        mode = CONTOUR_MODE[self._mode]
+        method = CONTOUR_METHOD[self._method]
+        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+        cnts, _ = cv2.findContours(img, mode, method)
+        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
+        if self._bbox == RECT_CONTOUR:
+            bboxs = [cv2.boundingRect(cnt) for cnt in cnts]
+            print(bboxs)
+            for x, y, w, h in bboxs:
+                img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), thickness=2)
+        elif self._bbox == MINRECT_CONTOUR:
+            bboxs = [np.int0(cv2.boxPoints(cv2.minAreaRect(cnt))) for cnt in cnts]
+            img = cv2.drawContours(img, bboxs, -1, (255, 0, 0), thickness=2)
+        elif self._bbox == MINCIRCLE_CONTOUR:
+            circles = [cv2.minEnclosingCircle(cnt) for cnt in cnts]
+            print(circles)
+            for (x, y), r in circles:
+                img = cv2.circle(img, (int(x), int(y)), int(r), (255, 0, 0), thickness=2)
+        elif self._bbox == NORMAL_CONTOUR:
+            img = cv2.drawContours(img, cnts, -1, (255, 0, 0), thickness=2)
+
+        return img
+
+
+class EqualizeItem(MyItem):
+    def __init__(self, parent=None):
+        super().__init__(' 均衡化 ', parent=parent)
+        self._blue = True
+        self._green = True
+        self._red = True
+
+    def __call__(self, img):
+        b, g, r = cv2.split(img)
+        if self._blue:
+            b = cv2.equalizeHist(b)
+        if self._green:
+            g = cv2.equalizeHist(g)
+        if self._red:
+            r = cv2.equalizeHist(r)
+        return cv2.merge((b, g, r))
+
+
+class HoughLineItem(MyItem):
+    def __init__(self, parent=None):
+        super(HoughLineItem, self).__init__('直线检测', parent=parent)
+        self._rho = 1
+        self._theta = np.pi / 180
+        self._thresh = 10
+        self._min_length = 20
+        self._max_gap = 5
+
+    def __call__(self, img):
+        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+        lines = cv2.HoughLinesP(img, self._rho, self._theta, self._thresh, minLineLength=self._min_length,
+                                maxLineGap=self._max_gap)
+        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
+        if lines is None:
+            return img
+        for line in lines:
+            for x1, y1, x2, y2 in line:
+                img = cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), thickness=2)
+        return img
+
+
+class GammaItem(MyItem):
+    def __init__(self, parent=None):
+        super(GammaItem, self).__init__('伽马校正', parent=parent)
+        self._gamma = 1
+
+    def __call__(self, img):
+        gamma_table = [np.power(x / 255.0, self._gamma) * 255.0 for x in range(256)]
+        gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
+        return cv2.LUT(img, gamma_table)
+
+        # 重构:
+        # 裁剪:
+
+
+class RotateAnyItem(MyItem):  # 任意旋转
+    def __init__(self, parent=None):
+        super(RotateAnyItem, self).__init__('任意旋转', parent=parent)
+        self._angle = 0
+
+    def __call__(self, img):
+        img = imutils.rotate_bound(img, self._angle)
+        return img
+
+
+class RotateLeftItem(MyItem):  # 90度旋转
+    def __init__(self, parent=None):
+        super(RotateLeftItem, self).__init__('向左旋转', parent=parent)
+
+    def __call__(self, img):
+        img = imutils.rotate_bound(img, -90)
+        return img
+
+
+class RotateRightItem(MyItem):  # 90度旋转
+    def __init__(self, parent=None):
+        super(RotateRightItem, self).__init__('向右旋转', parent=parent)
+
+    def __call__(self, img):
+        img = imutils.rotate_bound(img, 90)
+        return img
+
+
+class UpDownItem(MyItem):
+    def __init__(self, parent=None):
+        super(UpDownItem, self).__init__('上下翻折', parent=parent)
+
+    def __call__(self, img):
+        img = cv2.flip(img, 0)
+        return img
+
+
+# 光效
+
+
+class ExposureItem(MyItem):
+    def __init__(self, parent=None):
+        super(ExposureItem, self).__init__('曝光', parent=parent)
+        self._alpha = 1
+
+    def __call__(self, img):
+        blank = np.zeros(img.shape, img.dtype)
+        img = cv2.addWeighted(img, self._alpha, blank, 1 - self._alpha, 0)
+        return img
+
+
+class LightItem(MyItem):
+    def __init__(self, parent=None):
+        super(LightItem, self).__init__('亮度调节', parent=parent)
+        self._beta = 0
+
+    def __call__(self, img):
+        blank = np.zeros(img.shape, img.dtype)
+        img = cv2.addWeighted(img, 1, blank, 0, self._beta)
+        return img
+
+
+class ContrastItem(MyItem):
+    def __init__(self, parent=None):
+        super(ContrastItem, self).__init__('对比度调节', parent=parent)
+        self._alpha = 1
+
+    def __call__(self, img):
+        dst = np.ones(img.shape)
+        img = np.uint8(np.clip(self._alpha * (img - 127 * dst) + 127 * dst, 0, 255))
+        return img
+
+        #  色彩:
+
+
+class ColorTemperatureItem(MyItem):
+    def __init__(self, parent=None):
+        super(ColorTemperatureItem, self).__init__('色温调节', parent=parent)
+        self._n = 50
+
+    def __call__(self, img):
+        level = self._n / 2
+        # src = img.clone()
+        info = img.shape
+        row = info[0]
+        col = info[1]
+        for i in range(0, row):
+            for j in range(0, col):
+                (r, b, g) = img[i, j]
+                rr = r - level
+                bb = b - level
+                gg = g + level
+                if rr > 255:
+                    rr = 255
+                elif rr < 0:
+                    rr = 0
+                if bb > 255:
+                    bb = 255
+                elif bb < 0:
+                    bb = 0
+                if gg > 255:
+                    gg = 255
+                elif gg < 0:
+                    gg = 0
+                img[i, j] = (rr, bb, gg)
+        return img
+
+
+class HueItem(MyItem):
+    def __init__(self, parent=None):
+        super(HueItem, self).__init__('色调调节', parent=parent)
+        self._n = 50
+
+    def __call__(self, img):
+        level = self._n / 2
+        # src = img.clone()
+        info = img.shape
+        row = info[0]
+        col = info[1]
+        for i in range(0, row):
+            for j in range(0, col):
+                (r, b, g) = img[i, j]
+                rr = r + level
+                bb = b - level
+                gg = g + level
+                if rr > 255:
+                    rr = 255
+                elif rr < 0:
+                    rr = 0
+                if bb > 255:
+                    bb = 255
+                elif bb < 0:
+                    bb = 0
+                if gg > 255:
+                    gg = 255
+                elif gg < 0:
+                    gg = 0
+                img[i, j] = (rr, bb, gg)
+        return img
+
+
+class SaturationItem(MyItem):
+    def __init__(self, parent=None):
+        super(SaturationItem, self).__init__('饱和度调节', parent=parent)
+        self._x = 0
+
+    def __call__(self, img):
+        img_t = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        # 获取hsv
+        h, s, v = cv2.split(img_t)
+        # 增加饱和度 饱和度越低,越接近灰度图像
+        s1 = np.clip(cv2.add(s, self._x), 0, 255)
+        img = np.uint8(cv2.merge((h, s1, v)))
+        img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR)
+        return img
+
+        # HSL:
+
+
+class HSLRedItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLRedItem, self).__init__('红色', parent=parent)
+        self._red_param_s = 1.0
+        self._red_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._red_param_v - 1.0
+        value2 = self._red_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 0 < h < 10 or 156 < h < 180:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class HSLOrangeItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLOrangeItem, self).__init__('橙色', parent=parent)
+        self._orange_param_s = 1.0
+        self._orange_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._orange_param_v - 1.0
+        value2 = self._orange_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 11 < h < 25:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class HSLYellowItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLYellowItem, self).__init__('黄色', parent=parent)
+        self._yellow_param_s = 1.0
+        self._yellow_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._yellow_param_v - 1.0
+        value2 = self._yellow_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 26 < h < 34:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class HSLGreenItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLGreenItem, self).__init__('绿色', parent=parent)
+        self._green_param_s = 1.0
+        self._green_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._green_param_v - 1.0
+        value2 = self._green_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 35 < h < 77:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class HSLCyanItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLCyanItem, self).__init__('青色', parent=parent)
+        self._cyan_param_s = 1.0
+        self._cyan_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._cyan_param_v - 1.0
+        value2 = self._cyan_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 78 < h < 99:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class HSLBlueItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLBlueItem, self).__init__('蓝色', parent=parent)
+        self._blue_param_s = 1.0
+        self._blue_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._blue_param_v - 1.0
+        value2 = self._blue_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 100 < h < 124:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class HSLPurpleItem(MyItem):
+    def __init__(self, parent=None):
+        super(HSLPurpleItem, self).__init__('紫色', parent=parent)
+        self._purple_param_s = 1.0
+        self._purple_param_v = 1.0
+
+    def __call__(self, img):
+        img_hsl = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+        info = img.shape
+        height = info[0]
+        width = info[1]
+        value1 = self._purple_param_v - 1.0
+        value2 = self._purple_param_s - 1.0
+        for m in range(height):
+            for w in range(width):
+                h, s, v = img_hsl[m, w]
+                b, g, r = img[m, w]
+                tag = abs((int(b) - int(g)) * (int(g) - int(r)))
+                if 43 < s < 255 and 46 < v < 255 and tag > 1600:
+                    if 125 < h < 155:
+                        b = (b + (b - v) * value2)
+                        g = (g + (g - v) * value2)
+                        r = (r + (r - v) * value2)
+                        b = b + value1 * (255 - b)
+                        g = g + value1 * (255 - g)
+                        r = r + value1 * (255 - r)
+
+                img[m, w] = [b, g, r]
+
+        return img
+
+
+class PixelateItem(MyItem):
+    def __init__(self, parent=None):
+        super(PixelateItem, self).__init__('像素化', parent=parent)
+        self._size = 100
+
+    def __call__(self, img):
+        height, width = img.shape[:2]
+
+        # Desired "pixelated" size
+
+        w, h = (self._size, self._size)
+
+        # Resize input to "pixelated" size
+
+        temp = cv2.resize(img, (w, h), interpolation=cv2.INTER_LINEAR)
+
+        # Initialize output image
+
+        img = cv2.resize(temp, (width, height), interpolation=cv2.INTER_NEAREST)
+        return img
+
+
+class BlurItem(MyItem):
+    def __init__(self, parent=None):
+        super(BlurItem, self).__init__('模糊', parent=parent)
+        self._size = 5
+
+    def __call__(self, img):
+        img = cv2.blur(img, (self._size, self._size))
+        return img
+
+
+class CandyStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(CandyStyleTransformItem, self).__init__('candy', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/candy.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class CompositionStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(CompositionStyleTransformItem, self).__init__('composition', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/composition_vii.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class FeathersStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(FeathersStyleTransformItem, self).__init__('feathers', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/feathers.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class MuseStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(MuseStyleTransformItem, self).__init__('la_muse', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/la_muse.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class MosaicStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(MosaicStyleTransformItem, self).__init__('mosaic', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/mosaic.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class StarryNightStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(StarryNightStyleTransformItem, self).__init__('starry_night', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/starry_night.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class ScreamStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(ScreamStyleTransformItem, self).__init__('the_scream', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/the_scream.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class WaveStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(WaveStyleTransformItem, self).__init__('the_wave', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/the_wave.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class UdnieStyleTransformItem(MyItem):
+    def __init__(self, parent=None):
+        super(UdnieStyleTransformItem, self).__init__('udnie', parent=parent)
+
+    def __call__(self, img):
+        net = cv2.dnn.readNetFromTorch("./style/udnie.t7")
+        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
+        # img = cv2.imread("D:\\t\\1.jpg")
+        # res = cv2.resize(img, (500, 300))
+        row, column, _ = img.shape
+        blob = cv2.dnn.blobFromImage(img, 1.0, (column, row), (103.939, 116.779, 123.680), swapRB=False, crop=False)
+        net.setInput(blob)
+        out = net.forward()
+        out = out.reshape(3, out.shape[2], out.shape[3])
+        out[0] += 103.939
+        out[1] += 116.779
+        out[2] += 123.680
+        # output = out/255
+        out = out.transpose(1, 2, 0)
+        # output = output.transpose(1, 2, 0)
+        # cv2.imshow("out", output)
+        cv2.imwrite("tmp.jpg", out)
+        out2 = cv2.imread("tmp.jpg")
+        # out_res = cv2.resize(out, (500, 300))
+        return out2
+
+
+class ClarityItem(MyItem):
+    def __init__(self, parent=None):
+        super(ClarityItem, self).__init__('锐化', parent=parent)
+
+    def __call__(self, img):
+        kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
+        dst = cv2.filter2D(img, -1, kernel=kernel)
+        return dst
+
+
+class NoiseItem(MyItem):
+    def __init__(self, parent=None):
+        super(NoiseItem, self).__init__('噪点', parent=parent)
+
+    def __call__(self, img):
+        num = int(0.02 * img.shape[0] * img.shape[1])  # 椒盐噪声点数量
+        random.randint(0, img.shape[0])
+        img2 = img.copy()
+        for i in range(num):
+            X = random.randint(0, img2.shape[0] - 1)  # 从0到图像长度之间的一个随机整数,因为是闭区间所以-1
+            Y = random.randint(0, img2.shape[1] - 1)
+            if random.randint(0, 1) == 0:  # 黑白色概率55开
+                img2[X, Y] = (255, 255, 255)  # 白色
+            else:
+                img2[X, Y] = (0, 0, 0)  # 黑色
+        return img2
+
+
+class ImageCutItem(MyItem):
+    def __init__(self, parent=None):
+        super(ImageCutItem, self).__init__('裁剪', parent=parent)
+        self._x1 = 0
+        self._x2 = 300
+        self._y1 = 200
+        self._y2 = 600
+
+    def __call__(self, img):
+        dst = img[self._y1:self._y2, self._x1:self._x2]
+        return dst
+
+
+
diff --git a/custom/listWidgets.py b/custom/listWidgets.py
new file mode 100644
index 0000000..4c955a5
--- /dev/null
+++ b/custom/listWidgets.py
@@ -0,0 +1,310 @@
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+
+from config import items, items1, items2, items3, items4, items5, items6, items7
+
+
+class MyListWidget(QListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.mainwindow = parent
+        self.setDragEnabled(True)
+        # 选中不显示虚线
+        # self.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.setFocusPolicy(Qt.NoFocus)
+
+
+class UsedListWidget(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setAcceptDrops(True)
+        self.setFlow(QListView.TopToBottom)  # 设置列表方向
+        self.setDefaultDropAction(Qt.MoveAction)  # 设置拖放为移动而不是复制一个
+        self.setDragDropMode(QAbstractItemView.InternalMove)  # 设置拖放模式, 内部拖放
+        self.itemClicked.connect(self.show_attr)
+        self.setMinimumWidth(200)
+
+        self.move_item = None
+
+    def contextMenuEvent(self, e):
+        # 右键菜单事件
+        item = self.itemAt(self.mapFromGlobal(QCursor.pos()))
+        if not item:
+            return  # 判断是否是空白区域
+        menu = QMenu()
+        delete_action = QAction('删除', self)
+        delete_action.triggered.connect(lambda: self.delete_item(item))  # 传递额外值
+        menu.addAction(delete_action)
+        menu.exec(QCursor.pos())
+
+    def delete_item(self, item):
+        # 删除操作
+        self.takeItem(self.row(item))
+        self.mainwindow.update_image()  # 更新frame
+        self.mainwindow.dock_attr.close()
+
+    def dropEvent(self, event):
+        super().dropEvent(event)
+        self.mainwindow.update_image()
+
+    def show_attr(self):
+        item = self.itemAt(self.mapFromGlobal(QCursor.pos()))
+        if not item:
+            return
+        param = item.get_params()  # 获取当前item的属性
+        if type(item) in items:
+            index = items.index(type(item))  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(index)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items1:
+            index = items1.index(type(item))  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(index + 10)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items2:
+            index = items2.index(type(item))  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(index + 15)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items3:
+            index = items3.index(type(item))  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(index + 18)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items4:
+            index = items4.index(type(item))  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(index + 21)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items5:
+            index = items5.index(type(item))  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(index + 28)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items6:  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(30)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+        if type(item) in items7:  # 获取item对应的table索引
+            self.mainwindow.stackedWidget.setCurrentIndex(30)
+            self.mainwindow.stackedWidget.currentWidget().update_params(param)  # 更新对应的table
+            self.mainwindow.dock_attr.show()
+
+
+class FuncListWidget(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget1(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items1:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items1:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget2(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items2:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items2:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget3(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items3:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items3:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget4(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items4:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items4:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget5(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items5:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items5:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget6(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items6:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items6:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
+
+class FuncListWidget7(MyListWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.setFixedHeight(64 * 3)
+        self.setFlow(QListView.LeftToRight)  # 设置列表方向
+        self.setViewMode(QListView.IconMode)  # 设置列表模式
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  # 关掉滑动条
+        self.setAcceptDrops(False)
+        for itemType in items7:
+            self.addItem(itemType())
+        self.itemClicked.connect(self.add_used_function)
+
+    def add_used_function(self):
+        func_item = self.currentItem()
+        if type(func_item) in items7:
+            use_item = type(func_item)()
+            self.mainwindow.useListWidget.addItem(use_item)
+            self.mainwindow.update_image()
+
+    def enterEvent(self, event):
+        self.setCursor(Qt.PointingHandCursor)
+
+    def leaveEvent(self, event):
+        self.setCursor(Qt.ArrowCursor)
+        self.setCurrentRow(-1)  # 取消选中状态
+
diff --git a/custom/stackedWidget.py b/custom/stackedWidget.py
new file mode 100644
index 0000000..e7290a9
--- /dev/null
+++ b/custom/stackedWidget.py
@@ -0,0 +1,10 @@
+from custom.tableWidget import *
+from config import tables
+
+
+class StackedWidget(QStackedWidget):
+    def __init__(self, parent):
+        super().__init__(parent=parent)
+        for table in tables:
+            self.addWidget(table(parent=parent))
+        self.setMinimumWidth(200)
diff --git a/custom/styleSheet.qss b/custom/styleSheet.qss
new file mode 100644
index 0000000..a244671
--- /dev/null
+++ b/custom/styleSheet.qss
@@ -0,0 +1,86 @@
+*{
+    font-family: 微软雅黑;
+    color: #BBBBBB;
+    background-color: #2F2F2F;
+}
+
+/* 设置目录树样式 */
+QTreeView{
+    show-decoration-selected: 1;
+}
+QTreeView::item{
+    height: 30px;
+}
+QTreeView::item:hover, QTreeView::branch:hover{
+    background: #4B6EAF;
+}
+QTreeView::item:selected, QTreeView::branch:selected{
+    background: #4B6EAF;
+}
+QTreeView::branch{
+    color: #BBBBBB;
+}
+QTreeView::branch:has-children:!has-siblings:closed,
+QTreeView::branch:closed:has-children:has-siblings {
+    border-image: none;
+    image: url(icons/branch-close.png);
+}
+QTreeView::branch:open:has-children:!has-siblings,
+QTreeView::branch:open:has-children:has-siblings  {
+    border-image: none;
+    image: url(icons/branch-open.png);
+}
+
+/* 设置标签样式 */
+QLabel{
+    font-size: 18px;
+    border: 1px solid #BBBBBB;
+    border-width: 1px 1px 0px 1px;
+}
+
+/* 设置视图样式 */
+QGraphicsView{
+    border: 1px solid #BBBBBB;
+    background-color: #444444;
+}
+
+/* 设置列表样式 */
+QListWidget::Item{
+    border: 1px solid #BBBBBB;
+    font-size: 20px;
+    background: #717678;
+    color: #DDDDDD;
+}
+
+QListWidget::Item:hover{
+    background: #4B6EAF;
+}
+
+FuncListWidget::Item{
+    border-style: inset;
+    border-radius: 8px;
+    border: 1px solid #999999;
+    margin:0px 1px 0px 0px
+}
+
+UsedListWidget::Item{
+    border: 2px solid #999999;
+    margin:0px 0px 1px 0px
+}
+
+UsedListWidget::Item:selected{
+    background: #99CCFF;
+}
+
+
+/* 设置表格样式 */
+QTableWidget{
+    alternate-background-color: #444444;
+}
+
+
+QToolButton:hover{
+    background: #4B6EAF;
+}
+
+
diff --git a/custom/tableWidget.py b/custom/tableWidget.py
new file mode 100644
index 0000000..f8238bd
--- /dev/null
+++ b/custom/tableWidget.py
@@ -0,0 +1,690 @@
+from PyQt5.QtWidgets import *
+from PyQt5.QtCore import *
+
+
+class TableWidget(QTableWidget):
+    def __init__(self, parent=None):
+        super(TableWidget, self).__init__(parent=parent)
+        self.mainwindow = parent
+        self.setShowGrid(True)  # 显示网格
+        self.setAlternatingRowColors(True)  # 隔行显示颜色
+        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.horizontalHeader().setVisible(False)
+        self.verticalHeader().setVisible(False)
+        self.horizontalHeader().sectionResizeMode(QHeaderView.Stretch)
+        self.verticalHeader().sectionResizeMode(QHeaderView.Stretch)
+        self.horizontalHeader().setStretchLastSection(True)
+        self.setFocusPolicy(Qt.NoFocus)
+
+    def signal_connect(self):
+        for spinbox in self.findChildren(QSpinBox):
+            spinbox.valueChanged.connect(self.update_item)
+        for doublespinbox in self.findChildren(QDoubleSpinBox):
+            doublespinbox.valueChanged.connect(self.update_item)
+        for combox in self.findChildren(QComboBox):
+            combox.currentIndexChanged.connect(self.update_item)
+        for checkbox in self.findChildren(QCheckBox):
+            checkbox.stateChanged.connect(self.update_item)
+
+    def update_item(self):
+        param = self.get_params()
+        self.mainwindow.useListWidget.currentItem().update_params(param)
+        self.mainwindow.update_image()
+
+    def update_params(self, param=None):
+        for key in param.keys():
+            box = self.findChild(QWidget, name=key)
+            if isinstance(box, QSpinBox) or isinstance(box, QDoubleSpinBox):
+                box.setValue(param[key])
+            elif isinstance(box, QComboBox):
+                box.setCurrentIndex(param[key])
+            elif isinstance(box, QCheckBox):
+                box.setChecked(param[key])
+
+    def get_params(self):
+        param = {}
+        for spinbox in self.findChildren(QSpinBox):
+            param[spinbox.objectName()] = spinbox.value()
+        for doublespinbox in self.findChildren(QDoubleSpinBox):
+            param[doublespinbox.objectName()] = doublespinbox.value()
+        for combox in self.findChildren(QComboBox):
+            param[combox.objectName()] = combox.currentIndex()
+        for combox in self.findChildren(QCheckBox):
+            param[combox.objectName()] = combox.isChecked()
+        return param
+
+
+class GrayingTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(GrayingTableWidget, self).__init__(parent=parent)
+
+
+class FilterTabledWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(FilterTabledWidget, self).__init__(parent=parent)
+
+        self.kind_comBox = QComboBox()
+        self.kind_comBox.addItems(['均值滤波', '高斯滤波', '中值滤波'])
+        self.kind_comBox.setObjectName('kind')
+
+        self.ksize_spinBox = QSpinBox()
+        self.ksize_spinBox.setObjectName('ksize')
+        self.ksize_spinBox.setMinimum(1)
+        self.ksize_spinBox.setSingleStep(2)
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('类型'))
+        self.setCellWidget(0, 1, self.kind_comBox)
+        self.setItem(1, 0, QTableWidgetItem('核大小'))
+        self.setCellWidget(1, 1, self.ksize_spinBox)
+
+        self.signal_connect()
+
+
+class MorphTabledWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(MorphTabledWidget, self).__init__(parent=parent)
+
+        self.op_comBox = QComboBox()
+        self.op_comBox.addItems(['腐蚀操作', '膨胀操作', '开操作', '闭操作', '梯度操作', '顶帽操作', '黑帽操作'])
+        self.op_comBox.setObjectName('op')
+
+        self.ksize_spinBox = QSpinBox()
+        self.ksize_spinBox.setMinimum(1)
+        self.ksize_spinBox.setSingleStep(2)
+        self.ksize_spinBox.setObjectName('ksize')
+
+        self.kshape_comBox = QComboBox()
+        self.kshape_comBox.addItems(['方形', '十字形', '椭圆形'])
+        self.kshape_comBox.setObjectName('kshape')
+
+        self.setColumnCount(2)
+        self.setRowCount(3)
+        self.setItem(0, 0, QTableWidgetItem('类型'))
+        self.setCellWidget(0, 1, self.op_comBox)
+        self.setItem(1, 0, QTableWidgetItem('核大小'))
+        self.setCellWidget(1, 1, self.ksize_spinBox)
+        self.setItem(2, 0, QTableWidgetItem('核形状'))
+        self.setCellWidget(2, 1, self.kshape_comBox)
+        self.signal_connect()
+
+
+class GradTabledWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(GradTabledWidget, self).__init__(parent=parent)
+
+        self.kind_comBox = QComboBox()
+        self.kind_comBox.addItems(['Sobel算子', 'Scharr算子', 'Laplacian算子'])
+        self.kind_comBox.setObjectName('kind')
+
+        self.ksize_spinBox = QSpinBox()
+        self.ksize_spinBox.setMinimum(1)
+        self.ksize_spinBox.setSingleStep(2)
+        self.ksize_spinBox.setObjectName('ksize')
+
+        self.dx_spinBox = QSpinBox()
+        self.dx_spinBox.setMaximum(1)
+        self.dx_spinBox.setMinimum(0)
+        self.dx_spinBox.setSingleStep(1)
+        self.dx_spinBox.setObjectName('dx')
+
+        self.dy_spinBox = QSpinBox()
+        self.dy_spinBox.setMaximum(1)
+        self.dy_spinBox.setMinimum(0)
+        self.dy_spinBox.setSingleStep(1)
+        self.dy_spinBox.setObjectName('dy')
+
+        self.setColumnCount(2)
+        self.setRowCount(4)
+
+        self.setItem(0, 0, QTableWidgetItem('类型'))
+        self.setCellWidget(0, 1, self.kind_comBox)
+        self.setItem(1, 0, QTableWidgetItem('核大小'))
+        self.setCellWidget(1, 1, self.ksize_spinBox)
+        self.setItem(2, 0, QTableWidgetItem('x方向'))
+        self.setCellWidget(2, 1, self.dx_spinBox)
+        self.setItem(3, 0, QTableWidgetItem('y方向'))
+        self.setCellWidget(3, 1, self.dy_spinBox)
+
+        self.signal_connect()
+
+
+class ThresholdTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(ThresholdTableWidget, self).__init__(parent=parent)
+
+        self.thresh_spinBox = QSpinBox()
+        self.thresh_spinBox.setObjectName('thresh')
+        self.thresh_spinBox.setMaximum(255)
+        self.thresh_spinBox.setMinimum(0)
+        self.thresh_spinBox.setSingleStep(1)
+
+        self.maxval_spinBox = QSpinBox()
+        self.maxval_spinBox.setObjectName('maxval')
+        self.maxval_spinBox.setMaximum(255)
+        self.maxval_spinBox.setMinimum(0)
+        self.maxval_spinBox.setSingleStep(1)
+
+        self.method_comBox = QComboBox()
+        self.method_comBox.addItems(['二进制阈值化', '反二进制阈值化', '截断阈值化', '阈值化为0', '反阈值化为0', '大津算法'])
+        self.method_comBox.setObjectName('method')
+
+        self.setColumnCount(2)
+        self.setRowCount(3)
+
+        self.setItem(0, 0, QTableWidgetItem('类型'))
+        self.setCellWidget(0, 1, self.method_comBox)
+        self.setItem(1, 0, QTableWidgetItem('阈值'))
+        self.setCellWidget(1, 1, self.thresh_spinBox)
+        self.setItem(2, 0, QTableWidgetItem('最大值'))
+        self.setCellWidget(2, 1, self.maxval_spinBox)
+
+        self.signal_connect()
+
+
+class EdgeTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(EdgeTableWidget, self).__init__(parent=parent)
+
+        self.thresh1_spinBox = QSpinBox()
+        self.thresh1_spinBox.setMinimum(0)
+        self.thresh1_spinBox.setMaximum(255)
+        self.thresh1_spinBox.setSingleStep(1)
+        self.thresh1_spinBox.setObjectName('thresh1')
+
+        self.thresh2_spinBox = QSpinBox()
+        self.thresh2_spinBox.setMinimum(0)
+        self.thresh2_spinBox.setMaximum(255)
+        self.thresh2_spinBox.setSingleStep(1)
+        self.thresh2_spinBox.setObjectName('thresh2')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+
+        self.setItem(0, 0, QTableWidgetItem('阈值1'))
+        self.setCellWidget(0, 1, self.thresh1_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('阈值2'))
+        self.setCellWidget(1, 1, self.thresh2_spinBox)
+        self.signal_connect()
+
+
+class ImageCutTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(ImageCutTableWidget, self).__init__(parent=parent)
+
+        self.x1_spinBox = QSpinBox()
+        self.x1_spinBox.setMinimum(1)
+        self.x1_spinBox.setMaximum(5000)
+        self.x1_spinBox.setSingleStep(1)
+        self.x1_spinBox.setObjectName('x1')
+
+        self.y1_spinBox = QSpinBox()
+        self.y1_spinBox.setMinimum(1)
+        self.y1_spinBox.setMaximum(5000)
+        self.y1_spinBox.setSingleStep(1)
+        self.y1_spinBox.setObjectName('y1')
+
+        self.x2_spinBox = QSpinBox()
+        self.x2_spinBox.setMinimum(1)
+        self.x2_spinBox.setMaximum(5000)
+        self.x2_spinBox.setSingleStep(1)
+        self.x2_spinBox.setObjectName('x2')
+
+        self.y2_spinBox = QSpinBox()
+        self.y2_spinBox.setMinimum(1)
+        self.y2_spinBox.setMaximum(5000)
+        self.y2_spinBox.setSingleStep(1)
+        self.y2_spinBox.setObjectName('y2')
+
+        self.setColumnCount(4)
+        self.setRowCount(2)
+
+        self.setItem(0, 0, QTableWidgetItem('x1'))
+        self.setCellWidget(0, 1, self.x1_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('y1'))
+        self.setCellWidget(1, 1, self.y1_spinBox)
+        self.setItem(2, 0, QTableWidgetItem('x2'))
+        self.setCellWidget(2, 1, self.x2_spinBox)
+        self.setItem(3, 0, QTableWidgetItem('y2'))
+        self.setCellWidget(3, 1, self.y2_spinBox)
+        self.signal_connect()
+
+
+class ContourTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(ContourTableWidget, self).__init__(parent=parent)
+
+        self.bbox_comBox = QComboBox()
+        self.bbox_comBox.addItems(['正常轮廓', '外接矩形', '最小外接矩形', '最小外接圆'])
+        self.bbox_comBox.setObjectName('bbox')
+
+        self.mode_comBox = QComboBox()
+        self.mode_comBox.addItems(['外轮廓', '轮廓列表', '外轮廓与内孔', '轮廓等级树'])
+        self.mode_comBox.setObjectName('mode')
+
+        self.method_comBox = QComboBox()
+        self.method_comBox.addItems(['无近似', '简易近似'])
+        self.method_comBox.setObjectName('method')
+
+        self.setColumnCount(2)
+        self.setRowCount(3)
+
+        self.setItem(0, 0, QTableWidgetItem('轮廓模式'))
+        self.setCellWidget(0, 1, self.mode_comBox)
+        self.setItem(1, 0, QTableWidgetItem('轮廓近似'))
+        self.setCellWidget(1, 1, self.method_comBox)
+        self.setItem(2, 0, QTableWidgetItem('边界模式'))
+        self.setCellWidget(2, 1, self.bbox_comBox)
+        self.signal_connect()
+
+
+class EqualizeTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(EqualizeTableWidget, self).__init__(parent=parent)
+        self.red_checkBox = QCheckBox()
+        self.red_checkBox.setObjectName('red')
+        self.red_checkBox.setTristate(False)
+        self.blue_checkBox = QCheckBox()
+        self.blue_checkBox.setObjectName('blue')
+        self.blue_checkBox.setTristate(False)
+        self.green_checkBox = QCheckBox()
+        self.green_checkBox.setObjectName('green')
+        self.green_checkBox.setTristate(False)
+
+        self.setColumnCount(2)
+        self.setRowCount(3)
+
+        self.setItem(0, 0, QTableWidgetItem('R通道'))
+        self.setCellWidget(0, 1, self.red_checkBox)
+        self.setItem(1, 0, QTableWidgetItem('G通道'))
+        self.setCellWidget(1, 1, self.green_checkBox)
+        self.setItem(2, 0, QTableWidgetItem('B通道'))
+        self.setCellWidget(2, 1, self.blue_checkBox)
+        self.signal_connect()
+
+
+class HoughLineTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HoughLineTableWidget, self).__init__(parent=parent)
+
+        self.thresh_spinBox = QSpinBox()
+        self.thresh_spinBox.setMinimum(0)
+        self.thresh_spinBox.setSingleStep(1)
+        self.thresh_spinBox.setObjectName('thresh')
+
+        self.min_length_spinBox = QSpinBox()
+        self.min_length_spinBox.setMinimum(0)
+        self.min_length_spinBox.setSingleStep(1)
+        self.min_length_spinBox.setObjectName('min_length')
+
+        self.max_gap_spinbox = QSpinBox()
+        self.max_gap_spinbox.setMinimum(0)
+        self.max_gap_spinbox.setSingleStep(1)
+        self.max_gap_spinbox.setObjectName('max_gap')
+
+        self.setColumnCount(2)
+        self.setRowCount(3)
+
+        self.setItem(0, 0, QTableWidgetItem('交点阈值'))
+        self.setCellWidget(0, 1, self.thresh_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('最小长度'))
+        self.setCellWidget(1, 1, self.min_length_spinBox)
+        self.setItem(2, 0, QTableWidgetItem('最大间距'))
+        self.setCellWidget(2, 1, self.max_gap_spinbox)
+        self.signal_connect()
+
+
+class LightTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(LightTableWidget, self).__init__(parent=parent)
+
+        self.alpha_spinBox = QDoubleSpinBox()
+        self.alpha_spinBox.setMinimum(0)
+        self.alpha_spinBox.setMaximum(3)
+        self.alpha_spinBox.setSingleStep(0.1)
+        self.alpha_spinBox.setObjectName('alpha')
+
+        self.beta_spinbox = QSpinBox()
+        self.beta_spinbox.setMinimum(0)
+        self.beta_spinbox.setSingleStep(1)
+        self.beta_spinbox.setObjectName('beta')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+
+        self.setItem(0, 0, QTableWidgetItem('alpha'))
+        self.setCellWidget(0, 1, self.alpha_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('beta'))
+        self.setCellWidget(1, 1, self.beta_spinbox)
+        self.signal_connect()
+
+
+class GammaITabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(GammaITabelWidget, self).__init__(parent=parent)
+        self.gamma_spinbox = QDoubleSpinBox()
+        self.gamma_spinbox.setMinimum(0)
+        self.gamma_spinbox.setSingleStep(0.1)
+        self.gamma_spinbox.setObjectName('gamma')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+
+        self.setItem(0, 0, QTableWidgetItem('gamma'))
+        self.setCellWidget(0, 1, self.gamma_spinbox)
+        self.signal_connect()
+
+
+class RotateAnyTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(RotateAnyTabelWidget, self).__init__(parent=parent)
+        self.angle_spinBox = QSpinBox()
+        self.angle_spinBox.setMinimum(0)
+        self.angle_spinBox.setSingleStep(1)
+        self.angle_spinBox.setMaximum(360)
+        self.angle_spinBox.setObjectName('angle')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+        self.setItem(0, 0, QTableWidgetItem('旋转角度'))
+        self.setCellWidget(0, 1, self.angle_spinBox)
+        self.signal_connect()
+
+
+class ExposureTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(ExposureTabelWidget, self).__init__(parent=parent)
+
+        self.alpha_spinBox = QDoubleSpinBox()
+        self.alpha_spinBox.setMinimum(0)
+        self.alpha_spinBox.setMaximum(3)
+        self.alpha_spinBox.setSingleStep(0.1)
+        self.alpha_spinBox.setObjectName('alpha')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+
+        self.setItem(0, 0, QTableWidgetItem('曝光度'))
+        self.setCellWidget(0, 1, self.alpha_spinBox)
+        self.signal_connect()
+
+
+class ContrastTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(ContrastTabelWidget, self).__init__(parent=parent)
+
+        self.alpha_spinBox = QDoubleSpinBox()
+        self.alpha_spinBox.setMinimum(0)
+        self.alpha_spinBox.setSingleStep(0.1)
+        self.alpha_spinBox.setObjectName('alpha')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+
+        self.setItem(0, 0, QTableWidgetItem('对比度'))
+        self.setCellWidget(0, 1, self.alpha_spinBox)
+        self.signal_connect()
+
+
+class ColorTemperatureTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(ColorTemperatureTabelWidget, self).__init__(parent=parent)
+        self.alpha_spinBox = QSpinBox()
+        self.alpha_spinBox.setRange(-200, 200)
+        self.alpha_spinBox.setSingleStep(1)
+        self.alpha_spinBox.setObjectName('n')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+        self.setItem(0, 0, QTableWidgetItem('色温'))
+        self.setCellWidget(0, 1, self.alpha_spinBox)
+        self.signal_connect()
+
+
+class HueTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HueTabelWidget, self).__init__(parent=parent)
+        self.alpha_spinBox = QSpinBox()
+        self.alpha_spinBox.setRange(-200, 200)
+        self.alpha_spinBox.setSingleStep(1)
+        self.alpha_spinBox.setObjectName('n')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+        self.setItem(0, 0, QTableWidgetItem('色调'))
+        self.setCellWidget(0, 1, self.alpha_spinBox)
+        self.signal_connect()
+
+
+class SaturationTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(SaturationTabelWidget, self).__init__(parent=parent)
+        self.angle_spinBox = QSpinBox()
+        self.angle_spinBox.setRange(-50, 50)
+        self.angle_spinBox.setSingleStep(1)
+        self.angle_spinBox.setObjectName('x')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+        self.setItem(0, 0, QTableWidgetItem('饱和度'))
+        self.setCellWidget(0, 1, self.angle_spinBox)
+        self.signal_connect()
+
+
+class PixelateTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(PixelateTabelWidget, self).__init__(parent=parent)
+        self.size_spinBox = QSpinBox()
+        self.size_spinBox.setRange(1, 1000)
+        self.size_spinBox.setSingleStep(10)
+        self.size_spinBox.setObjectName('size')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+        self.setItem(0, 0, QTableWidgetItem('像素大小'))
+        self.setCellWidget(0, 1, self.size_spinBox)
+        self.signal_connect()
+
+
+class BlurTabelWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(BlurTabelWidget, self).__init__(parent=parent)
+        self.size_spinBox = QSpinBox()
+        self.size_spinBox.setRange(1, 100)
+        self.size_spinBox.setSingleStep(1)
+        self.size_spinBox.setObjectName('size')
+
+        self.setColumnCount(2)
+        self.setRowCount(1)
+        self.setItem(0, 0, QTableWidgetItem('模糊大小'))
+        self.setCellWidget(0, 1, self.size_spinBox)
+        self.signal_connect()
+
+
+class HSLRedWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLRedWidget, self).__init__(parent=parent)
+        self.red_param_s_spinBox = QDoubleSpinBox()
+        self.red_param_s_spinBox.setMinimum(0)
+        self.red_param_s_spinBox.setSingleStep(0.01)
+        self.red_param_s_spinBox.setMaximum(2)
+        self.red_param_s_spinBox.setObjectName('red_param_s')
+
+        self.red_param_v_spinBox = QDoubleSpinBox()
+        self.red_param_v_spinBox.setMinimum(0)
+        self.red_param_v_spinBox.setSingleStep(0.01)
+        self.red_param_v_spinBox.setMaximum(2)
+        self.red_param_v_spinBox.setObjectName('red_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('红色饱和度'))
+        self.setCellWidget(0, 1, self.red_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('红色亮度'))
+        self.setCellWidget(1, 1, self.red_param_s_spinBox)
+        self.signal_connect()
+
+
+class HSLOrangeWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLOrangeWidget, self).__init__(parent=parent)
+        self.orange_param_s_spinBox = QDoubleSpinBox()
+        self.orange_param_s_spinBox.setMinimum(0)
+        self.orange_param_s_spinBox.setSingleStep(0.01)
+        self.orange_param_s_spinBox.setMaximum(2)
+        self.orange_param_s_spinBox.setObjectName('orange_param_s')
+
+        self.orange_param_v_spinBox = QDoubleSpinBox()
+        self.orange_param_v_spinBox.setMinimum(0)
+        self.orange_param_v_spinBox.setSingleStep(0.01)
+        self.orange_param_v_spinBox.setMaximum(2)
+        self.orange_param_v_spinBox.setObjectName('orange_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('橙色饱和度'))
+        self.setCellWidget(0, 1, self.orange_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('橙色亮度'))
+        self.setCellWidget(1, 1, self.orange_param_s_spinBox)
+        self.signal_connect()
+
+
+class HSLYellowWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLYellowWidget, self).__init__(parent=parent)
+        self.yellow_param_s_spinBox = QDoubleSpinBox()
+        self.yellow_param_s_spinBox.setMinimum(0)
+        self.yellow_param_s_spinBox.setSingleStep(0.01)
+        self.yellow_param_s_spinBox.setMaximum(2)
+        self.yellow_param_s_spinBox.setObjectName('yellow_param_s')
+
+        self.yellow_param_v_spinBox = QDoubleSpinBox()
+        self.yellow_param_v_spinBox.setMinimum(0)
+        self.yellow_param_v_spinBox.setSingleStep(0.01)
+        self.yellow_param_v_spinBox.setMaximum(2)
+        self.yellow_param_v_spinBox.setObjectName('yellow_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('黄色饱和度'))
+        self.setCellWidget(0, 1, self.yellow_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('黄色亮度'))
+        self.setCellWidget(1, 1, self.yellow_param_s_spinBox)
+        self.signal_connect()
+
+
+class HSLGreenWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLGreenWidget, self).__init__(parent=parent)
+        self.green_param_s_spinBox = QDoubleSpinBox()
+        self.green_param_s_spinBox.setMinimum(0)
+        self.green_param_s_spinBox.setSingleStep(0.01)
+        self.green_param_s_spinBox.setMaximum(2)
+        self.green_param_s_spinBox.setObjectName('green_param_s')
+
+        self.green_param_v_spinBox = QDoubleSpinBox()
+        self.green_param_v_spinBox.setMinimum(0)
+        self.green_param_v_spinBox.setSingleStep(0.01)
+        self.green_param_v_spinBox.setMaximum(2)
+        self.green_param_v_spinBox.setObjectName('green_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('绿色饱和度'))
+        self.setCellWidget(0, 1, self.green_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('绿色亮度'))
+        self.setCellWidget(1, 1, self.green_param_s_spinBox)
+        self.signal_connect()
+
+
+class HSLCyanWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLCyanWidget, self).__init__(parent=parent)
+        self.cyan_param_s_spinBox = QDoubleSpinBox()
+        self.cyan_param_s_spinBox.setMinimum(0)
+        self.cyan_param_s_spinBox.setSingleStep(0.01)
+        self.cyan_param_s_spinBox.setMaximum(2)
+        self.cyan_param_s_spinBox.setObjectName('cyan_param_s')
+
+        self.cyan_param_v_spinBox = QDoubleSpinBox()
+        self.cyan_param_v_spinBox.setMinimum(0)
+        self.cyan_param_v_spinBox.setSingleStep(0.01)
+        self.cyan_param_v_spinBox.setMaximum(2)
+        self.cyan_param_v_spinBox.setObjectName('cyan_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('青色饱和度'))
+        self.setCellWidget(0, 1, self.cyan_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('青色亮度'))
+        self.setCellWidget(1, 1, self.cyan_param_s_spinBox)
+        self.signal_connect()
+
+
+class HSLBlueWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLBlueWidget, self).__init__(parent=parent)
+        self.blue_param_s_spinBox = QDoubleSpinBox()
+        self.blue_param_s_spinBox.setMinimum(0)
+        self.blue_param_s_spinBox.setSingleStep(0.01)
+        self.blue_param_s_spinBox.setMaximum(2)
+        self.blue_param_s_spinBox.setObjectName('blue_param_s')
+
+        self.blue_param_v_spinBox = QDoubleSpinBox()
+        self.blue_param_v_spinBox.setMinimum(0)
+        self.blue_param_v_spinBox.setSingleStep(0.01)
+        self.blue_param_v_spinBox.setMaximum(2)
+        self.blue_param_v_spinBox.setObjectName('blue_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('蓝色饱和度'))
+        self.setCellWidget(0, 1, self.blue_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('蓝色亮度'))
+        self.setCellWidget(1, 1, self.blue_param_s_spinBox)
+        self.signal_connect()
+
+
+class HSLPurpleWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(HSLPurpleWidget, self).__init__(parent=parent)
+        self.purple_param_s_spinBox = QDoubleSpinBox()
+        self.purple_param_s_spinBox.setMinimum(0)
+        self.purple_param_s_spinBox.setSingleStep(0.01)
+        self.purple_param_s_spinBox.setMaximum(2)
+        self.purple_param_s_spinBox.setObjectName('purple_param_s')
+
+        self.purple_param_v_spinBox = QDoubleSpinBox()
+        self.purple_param_v_spinBox.setMinimum(0)
+        self.purple_param_v_spinBox.setSingleStep(0.01)
+        self.purple_param_v_spinBox.setMaximum(2)
+        self.purple_param_v_spinBox.setObjectName('purple_param_v')
+
+        self.setColumnCount(2)
+        self.setRowCount(2)
+        self.setItem(0, 0, QTableWidgetItem('紫色饱和度'))
+        self.setCellWidget(0, 1, self.purple_param_v_spinBox)
+        self.setItem(1, 0, QTableWidgetItem('紫色亮度'))
+        self.setCellWidget(1, 1, self.purple_param_s_spinBox)
+        self.signal_connect()
+
+
+class StyleTransformTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(StyleTransformTableWidget, self).__init__(parent=parent)
+
+
+class RotateLeftTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(RotateLeftTableWidget, self).__init__(parent=parent)
+
+
+class RotateRightTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(RotateRightTableWidget, self).__init__(parent=parent)
+
+
+class UpDownTableWidget(TableWidget):
+    def __init__(self, parent=None):
+        super(UpDownTableWidget, self).__init__(parent=parent)
\ No newline at end of file
diff --git a/custom/treeView.py b/custom/treeView.py
new file mode 100644
index 0000000..52c31f1
--- /dev/null
+++ b/custom/treeView.py
@@ -0,0 +1,35 @@
+import cv2
+import numpy as np
+from PyQt5.QtWidgets import *
+from PyQt5.QtCore import *
+
+
+class FileSystemTreeView(QTreeView, QDockWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.mainwindow = parent
+        self.fileSystemModel = QFileSystemModel()
+        self.fileSystemModel.setRootPath('.')
+        self.setModel(self.fileSystemModel)
+        # 隐藏size,date等列
+        self.setColumnWidth(0, 200)
+        self.setColumnHidden(1, True)
+        self.setColumnHidden(2, True)
+        self.setColumnHidden(3, True)
+        # 不显示标题栏
+        self.header().hide()
+        # 设置动画
+        self.setAnimated(True)
+        # 选中不显示虚线
+        self.setFocusPolicy(Qt.NoFocus)
+        self.doubleClicked.connect(self.select_image)
+        self.setMinimumWidth(200)
+
+    def select_image(self, file_index):
+        file_name = self.fileSystemModel.filePath(file_index)
+        if file_name.endswith(('.jpg', '.png', '.bmp')):
+            src_img = cv2.imdecode(np.fromfile(file_name, dtype=np.uint8), -1)
+            self.mainwindow.change_image(src_img)
+
+
+
diff --git a/custom/treeWidgets.py b/custom/treeWidgets.py
new file mode 100644
index 0000000..d5ac2e6
--- /dev/null
+++ b/custom/treeWidgets.py
@@ -0,0 +1,74 @@
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+
+from config import items
+
+
+class MyTreeWidget(QTreeWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent=parent)
+        self.mainwindow = parent
+        self.setDragEnabled(True)
+        # 选中不显示虚线
+        # self.setEditTriggers(QAbstractItemView.NoEditTriggers)
+        self.setFocusPolicy(Qt.NoFocus)
+
+
+class FuncTreeWidget(QTreeWidget):
+    def __init__(self, parent=None):
+        super(FuncTreeWidget, self).__init__(parent)
+
+        self.mainwindow = parent
+        # 根节点
+        root1 = QTreeWidgetItem(self)
+        root1.setText(0, '重构')  # 0代表第一列,即Key列
+        root1.setIcon(0, QIcon('icons/color.png'))  # 为节点设置图标
+        self.setColumnWidth(0, 200)  # 第一列列宽设为200
+        self.header().hide()
+        self.itemClicked.connect(self.function)
+
+        # 添加子节点1
+        child1 = QTreeWidgetItem(root1)
+        child1.setText(0, '裁剪')
+        child1.setIcon(0, QIcon('icons/color.png'))
+
+        root2 = QTreeWidgetItem(self)
+        root2.setText(0, '调整')  # 第一列Key为 子节点1
+        root2.setIcon(0, QIcon('icons/color.png'))
+
+        child4 = QTreeWidgetItem(root2)
+        child4.setText(0, '光效')
+        child4.setIcon(0, QIcon('icons/color.png'))
+
+        child5 = QTreeWidgetItem(root2)
+        child5.setText(0, '色彩')
+        child5.setIcon(0, QIcon('icons/color.png'))
+
+        child6 = QTreeWidgetItem(root2)
+        child6.setText(0, 'HSL')
+        child6.setIcon(0, QIcon('icons/color.png'))
+
+        child8 = QTreeWidgetItem(root2)
+        child8.setText(0, '质感')
+        child8.setIcon(0, QIcon('icons/color.png'))
+
+        child10 = QTreeWidgetItem(root2)
+        child10.setText(0, '特效')
+        child10.setIcon(0, QIcon('icons/color.png'))
+
+        root3 = QTreeWidgetItem(self)
+        root3.setText(0, '风格迁移')
+        root3.setIcon(0, QIcon('icons/color.png'))
+
+        root4 = QTreeWidgetItem(self)
+        root4.setText(0, '其他操作')
+        root4.setIcon(0, QIcon('icons/color.png'))
+
+        # 默认所有节点都处于展开状态
+        # self.expandAll()
+
+    def function(self):
+        func_item = self.currentItem()
+        self.mainwindow.update_dock(func_item.text(0))
+
diff --git a/flags.py b/flags.py
new file mode 100644
index 0000000..fbd4a70
--- /dev/null
+++ b/flags.py
@@ -0,0 +1,96 @@
+import cv2
+
+GRAYING_STACKED_WIDGET = 0
+FILTER_STACKED_WIDGET = 1
+MORPH_STACKED_WIDGET = 2
+GRAD_STACKED_WIDGET = 3
+THRESH_STACKED_WIDGET = 4
+EDGE_STACKED_WIDGET = 5
+
+BGR2GRAY_COLOR = 0
+GRAY2BGR_COLOR = 1
+COLOR = {
+    BGR2GRAY_COLOR: cv2.COLOR_BGR2GRAY,
+    GRAY2BGR_COLOR: cv2.COLOR_GRAY2BGR
+}
+
+MEAN_FILTER = 0
+GAUSSIAN_FILTER = 1
+MEDIAN_FILTER = 2
+
+ERODE_MORPH_OP = 0
+DILATE_MORPH_OP = 1
+OPEN_MORPH_OP = 2
+CLOSE_MORPH_OP = 3
+GRADIENT_MORPH_OP = 4
+TOPHAT_MORPH_OP = 5
+BLACKHAT_MORPH_OP = 6
+
+MORPH_OP = {
+    ERODE_MORPH_OP: cv2.MORPH_ERODE,
+    DILATE_MORPH_OP: cv2.MORPH_DILATE,
+    OPEN_MORPH_OP: cv2.MORPH_OPEN,
+    CLOSE_MORPH_OP: cv2.MORPH_CLOSE,
+    GRADIENT_MORPH_OP: cv2.MORPH_GRADIENT,
+    TOPHAT_MORPH_OP: cv2.MORPH_TOPHAT,
+    BLACKHAT_MORPH_OP: cv2.MORPH_BLACKHAT
+}
+
+RECT_MORPH_SHAPE = 0
+CROSS_MORPH_SHAPE = 1
+ELLIPSE_MORPH_SHAPE = 2
+
+MORPH_SHAPE = {
+    RECT_MORPH_SHAPE: cv2.MORPH_RECT,
+    CROSS_MORPH_SHAPE: cv2.MORPH_CROSS,
+    ELLIPSE_MORPH_SHAPE: cv2.MORPH_ELLIPSE
+}
+
+SOBEL_GRAD = 0
+SCHARR_GRAD = 1
+LAPLACIAN_GRAD = 2
+
+BINARY_THRESH_METHOD = 0
+BINARY_INV_THRESH_METHOD = 1
+TRUNC_THRESH_METHOD = 2
+TOZERO_THRESH_METHOD = 3
+TOZERO_INV_THRESH_METHOD = 4
+OTSU_THRESH_METHOD = 5
+THRESH_METHOD = {
+    BINARY_THRESH_METHOD: cv2.THRESH_BINARY,  # 0
+    BINARY_INV_THRESH_METHOD: cv2.THRESH_BINARY_INV,  # 1
+    TRUNC_THRESH_METHOD: cv2.THRESH_TRUNC,  # 2
+    TOZERO_THRESH_METHOD: cv2.THRESH_TOZERO,  # 3
+    TOZERO_INV_THRESH_METHOD: cv2.THRESH_TOZERO_INV,  # 4
+    OTSU_THRESH_METHOD: cv2.THRESH_OTSU  # 5
+}
+
+EXTERNAL_CONTOUR_MODE = 0
+LIST_CONTOUR_MODE = 1
+CCOMP_CONTOUR_MODE = 2
+TREE_CONTOUR_MODE = 3
+CONTOUR_MODE = {
+    EXTERNAL_CONTOUR_MODE: cv2.RETR_EXTERNAL,
+    LIST_CONTOUR_MODE: cv2.RETR_LIST,
+    CCOMP_CONTOUR_MODE: cv2.RETR_CCOMP,
+    TREE_CONTOUR_MODE: cv2.RETR_TREE
+}
+
+NONE_CONTOUR_METHOD = 0
+SIMPLE_CONTOUR_METHOD = 1
+CONTOUR_METHOD = {
+    NONE_CONTOUR_METHOD: cv2.CHAIN_APPROX_NONE,
+    SIMPLE_CONTOUR_METHOD: cv2.CHAIN_APPROX_SIMPLE
+}
+
+NORMAL_CONTOUR = 0
+RECT_CONTOUR = 1
+MINRECT_CONTOUR = 2
+MINCIRCLE_CONTOUR = 3
+
+
+# 均衡化
+BLUE_CHANNEL = 0
+GREEN_CHANNEL = 1
+RED_CHANNEL = 2
+ALL_CHANNEL = 3
diff --git a/icons/branch-close.png b/icons/branch-close.png
new file mode 100644
index 0000000..1a54719
Binary files /dev/null and b/icons/branch-close.png differ
diff --git a/icons/branch-open.png b/icons/branch-open.png
new file mode 100644
index 0000000..5b733fd
Binary files /dev/null and b/icons/branch-open.png differ
diff --git a/icons/color.png b/icons/color.png
new file mode 100644
index 0000000..e6be09f
Binary files /dev/null and b/icons/color.png differ
diff --git a/icons/main.png b/icons/main.png
new file mode 100644
index 0000000..c0dbddd
Binary files /dev/null and b/icons/main.png differ
diff --git a/icons/右旋转.png b/icons/右旋转.png
new file mode 100644
index 0000000..e845a3e
Binary files /dev/null and b/icons/右旋转.png differ
diff --git a/icons/左旋转.png b/icons/左旋转.png
new file mode 100644
index 0000000..4cac983
Binary files /dev/null and b/icons/左旋转.png differ
diff --git a/icons/直方图.png b/icons/直方图.png
new file mode 100644
index 0000000..81e507d
Binary files /dev/null and b/icons/直方图.png differ
diff --git a/style/candy.t7 b/style/candy.t7
new file mode 100644
index 0000000..69e37b1
Binary files /dev/null and b/style/candy.t7 differ
diff --git a/style/composition_vii.t7 b/style/composition_vii.t7
new file mode 100644
index 0000000..0201669
Binary files /dev/null and b/style/composition_vii.t7 differ
diff --git a/style/feathers.t7 b/style/feathers.t7
new file mode 100644
index 0000000..69c192d
Binary files /dev/null and b/style/feathers.t7 differ
diff --git a/style/la_muse.t7 b/style/la_muse.t7
new file mode 100644
index 0000000..b8176a7
Binary files /dev/null and b/style/la_muse.t7 differ
diff --git a/style/mosaic.t7 b/style/mosaic.t7
new file mode 100644
index 0000000..44aa0a1
Binary files /dev/null and b/style/mosaic.t7 differ
diff --git a/style/starry_night.t7 b/style/starry_night.t7
new file mode 100644
index 0000000..78a8e78
Binary files /dev/null and b/style/starry_night.t7 differ
diff --git a/style/the_scream.t7 b/style/the_scream.t7
new file mode 100644
index 0000000..f5e5736
Binary files /dev/null and b/style/the_scream.t7 differ
diff --git a/style/the_wave.t7 b/style/the_wave.t7
new file mode 100644
index 0000000..73af44b
Binary files /dev/null and b/style/the_wave.t7 differ
diff --git a/style/udnie.t7 b/style/udnie.t7
new file mode 100644
index 0000000..6249ef3
Binary files /dev/null and b/style/udnie.t7 differ
diff --git a/tmp.jpg b/tmp.jpg
new file mode 100644
index 0000000..fbec5e5
Binary files /dev/null and b/tmp.jpg differ