├── .idea
├── .gitignore
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── resource.iml
└── vcs.xml
├── README.md
├── README.pdf
├── __pycache__
├── config.cpython-37.pyc
├── flags.cpython-37.pyc
├── main.cpython-37.pyc
└── run.cpython-37.pyc
├── config.py
├── custom
├── ImageView.py
├── __pycache__
│ ├── ImageView.cpython-37.pyc
│ ├── graphicsView.cpython-37.pyc
│ ├── listWidgetItems.cpython-37.pyc
│ ├── listWidgets.cpython-37.pyc
│ ├── stackedWidget.cpython-37.pyc
│ ├── tableWidget.cpython-37.pyc
│ └── treeView.cpython-37.pyc
├── graphicsView.py
├── listWidgetItems.py
├── listWidgets.py
├── stackedWidget.py
├── tableWidget.py
└── treeView.py
├── flags.py
├── function
├── AddNoise
│ ├── ExponentialNoise.py
│ ├── GammaNoise.py
│ ├── GasussNoise.py
│ ├── ImpluseNoise.py
│ ├── RayleighNoise.py
│ ├── UniformNoise.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── ExponentialNoise.cpython-37.pyc
│ │ ├── GammaNoise.cpython-37.pyc
│ │ ├── GasussNoise.cpython-37.pyc
│ │ ├── ImpluseNoise.cpython-37.pyc
│ │ ├── RayleighNoise.cpython-37.pyc
│ │ ├── UniformNoise.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── ColorImageProcess
│ ├── HSIProcess.py
│ ├── PseudoColorTrans.py
│ ├── RGB2CMY.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── HSIProcess.cpython-37.pyc
│ │ ├── PseudoColorTrans.cpython-37.pyc
│ │ ├── RGB2CMY.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── FrequencyDomainFilter
│ ├── ButterWorthFilter.py
│ ├── GaussianFrequencyFilter.py
│ ├── IdealFilter.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── ButterWorthFilter.cpython-37.pyc
│ │ ├── GaussianFrequencyFilter.cpython-37.pyc
│ │ ├── IdealFilter.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── GeometricTrans
│ ├── ImageCut.py
│ ├── LargeSmall.py
│ ├── Mirror.py
│ ├── Ratate.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── ImageCut.cpython-37.pyc
│ │ ├── LargeSmall.cpython-37.pyc
│ │ ├── Mirror.cpython-37.pyc
│ │ ├── Ratate.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── GrayscaleTrans
│ ├── BGR2GRAY.py
│ ├── Binarization.py
│ ├── GammaTrans.py
│ ├── Reverse.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── BGR2GRAY.cpython-37.pyc
│ │ ├── Binarization.cpython-37.pyc
│ │ ├── GammaTrans.cpython-37.pyc
│ │ ├── Reverse.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── HistogramTrans
│ ├── Equalize.py
│ ├── HistogramMatch.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── Equalize.cpython-37.pyc
│ │ ├── HistogramMatch.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── IdCardPicGenerate
│ ├── IdCardPicGenerate.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── IdCardPicGenerate.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── SharpenTrans
│ ├── Laplacian.py
│ ├── Prewitt.py
│ ├── Robert.py
│ ├── SobelFilter.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── Laplacian.cpython-37.pyc
│ │ ├── Prewitt.cpython-37.pyc
│ │ ├── Robert.cpython-37.pyc
│ │ ├── SobelFilter.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── SmoothingTrans
│ ├── GaussianFilter.py
│ ├── MeanFilter.py
│ ├── MedianFilter.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── GaussianFilter.cpython-37.pyc
│ │ ├── MeanFilter.cpython-37.pyc
│ │ ├── MedianFilter.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
├── __init__.py
└── __pycache__
│ └── __init__.cpython-37.pyc
├── histogram.png
├── icons
├── branch-close.png
├── branch-open.png
├── color.png
├── main.png
├── 右旋转.png
├── 左旋转.png
└── 直方图.png
├── images
├── Aerial.png
├── beach.png
├── board_salt.tif
├── boy.png
├── boy_salt.png
├── breast.png
├── caricature.png
├── espace.png
├── lena (2).bmp
├── lena.bmp
├── watch.jpg
└── 界面.png
├── main.py
└── styleSheet.qss
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/resource.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### 数字图像处理系统
2 |
3 | #### 软件界面
4 |
5 | 
6 |
7 | 备注:界面代码参考自https://github.com/JiageWang/opencv-pyqt5
8 |
9 | ### 系统功能
10 |
11 | * 几何变换
12 | * 图像放大|缩小
13 | * 图像镜像
14 | * 图像旋转
15 | * 图像裁剪
16 | * 灰度变换
17 | * 图像灰度化
18 | * 图像反转
19 | * 图像二值化
20 | * 幂律变换
21 | * 直方图处理
22 | * 直方图均衡化
23 | * 直方图匹配
24 | * 平滑处理
25 | * 均值滤波
26 | * 中值滤波
27 | * 高斯滤波
28 | * 锐化处理
29 | * sobel算子
30 | * robert算子
31 | * prewitt算子
32 | * laplacian算子
33 | * 加性噪声
34 | * 高斯噪声
35 | * 瑞利噪声
36 | * 伽马噪声
37 | * 均匀噪声
38 | * 椒盐噪声
39 | * 指数噪声
40 | * 频域滤波
41 | * 理想低通|高通滤波
42 | * 巴特沃斯低通|高通滤波
43 | * 高斯低通|高通滤波
44 | * 理想带阻|带通滤波
45 | * 巴特沃斯带阻|带通滤波
46 | * 高斯带阻|带通滤波
47 | * 理想带阻|带通陷波滤波
48 | * 彩色图像处理
49 | * RGB转CMY
50 | * RGB转HSI
51 | * RGB各个成分的调节
52 | * 伪彩色图像生成
53 | * 证件照生成
54 |
55 |
56 |
57 | ### 运行环境
58 |
59 | - python-opencv4.2
60 | - pyqt5
61 | - matplotlib3.2.1
62 | - numpy1.18.4
63 | - dlib
64 |
65 |
66 |
67 | ### 使用说明
68 |
69 | > 配置好相关环境,直接运行main.py就ok
--------------------------------------------------------------------------------
/README.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/README.pdf
--------------------------------------------------------------------------------
/__pycache__/config.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/__pycache__/config.cpython-37.pyc
--------------------------------------------------------------------------------
/__pycache__/flags.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/__pycache__/flags.cpython-37.pyc
--------------------------------------------------------------------------------
/__pycache__/main.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/__pycache__/main.cpython-37.pyc
--------------------------------------------------------------------------------
/__pycache__/run.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/__pycache__/run.cpython-37.pyc
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | from custom.tableWidget import *
2 | from custom.listWidgetItems import *
3 |
4 |
5 | # Implemented functions
6 | items = [
7 | GeometricTransItem,
8 | GrayingItem,
9 | EqualizeItem,
10 | FilterItem,
11 | SharpenItem,
12 | AddNoiseItem,
13 | FrequencyFilterItem,
14 | SelectFilterItem,
15 | ColorImageProcessItem,
16 | IdCardPicGenerateItem,
17 | ]
18 |
19 | tables = [
20 | GeometricTransTableWight,
21 | GrayingTableWidget,
22 | EqualizeTableWidget,
23 | FilterTabledWidget,
24 | SharpenItemTableWidget,
25 | AddNoiseItemTableWidget,
26 | FrequencyFilterTabledWidget,
27 | SelectFilterTabledWidget,
28 | ColorImageProcessTabledWidget,
29 | IdCardPicGenerateTabledWidget,
30 | ]
31 |
32 |
--------------------------------------------------------------------------------
/custom/ImageView.py:
--------------------------------------------------------------------------------
1 | from cv2 import selectROI,imwrite
2 | from PyQt5.QtWidgets import QMainWindow, QFileDialog
3 |
4 |
5 | class childwindow1(QMainWindow):
6 | def __init__(self,parent=None):
7 | super(childwindow1, self).__init__(parent)
8 | def openfile(self):
9 | fname, _ = QFileDialog.getOpenFileName(self, 'Open file', '.', 'Image Files(*.jpg *.bmp *.png *.jpeg *.rgb *.tif)')
10 | return fname
11 | def selectROI(self,img):
12 | bbox = selectROI(img, False)
13 | cut = img[bbox[1]:bbox[1] + bbox[3], bbox[0]:bbox[0] + bbox[2]]
14 | imwrite('cut.jpg', cut)
15 |
16 |
--------------------------------------------------------------------------------
/custom/__pycache__/ImageView.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/ImageView.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/__pycache__/graphicsView.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/graphicsView.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/__pycache__/listWidgetItems.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/listWidgetItems.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/__pycache__/listWidgets.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/listWidgets.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/__pycache__/stackedWidget.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/stackedWidget.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/__pycache__/tableWidget.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/tableWidget.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/__pycache__/treeView.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/custom/__pycache__/treeView.cpython-37.pyc
--------------------------------------------------------------------------------
/custom/graphicsView.py:
--------------------------------------------------------------------------------
1 | from PyQt5.QtCore import Qt, QRectF
2 | from PyQt5.QtGui import QCursor, QImage, QPixmap
3 | from PyQt5.QtWidgets import QGraphicsView, QGraphicsPixmapItem, QGraphicsScene, QMenu, QAction, QFileDialog
4 | from cv2 import cvtColor,COLOR_BGR2RGB
5 |
6 | class GraphicsView(QGraphicsView):
7 | def __init__(self, parent=None):
8 | super(GraphicsView, self).__init__(parent=parent)
9 | self._zoom = 0
10 | self._empty = True
11 | self._photo = QGraphicsPixmapItem()
12 | self._scene = QGraphicsScene(self)
13 | self._scene.addItem(self._photo)
14 |
15 |
16 | self.setScene(self._scene)
17 | # self.setScene(self._scene1)
18 | self.setAlignment(Qt.AlignCenter) # 居中显示
19 | self.setDragMode(QGraphicsView.ScrollHandDrag) # 设置拖动
20 | self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
21 | self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
22 | self.setMinimumSize(640, 480)
23 |
24 | def contextMenuEvent(self, event):
25 | if not self.has_photo():
26 | return
27 | menu = QMenu()
28 | save_action = QAction('另存为', self)
29 | save_action.triggered.connect(self.save_current) # 传递额外值
30 | menu.addAction(save_action)
31 | menu.exec(QCursor.pos())
32 |
33 | def save_current(self):
34 | file_name = QFileDialog.getSaveFileName(self, '另存为', './', 'Image files(*.jpg *.gif *.png)')[0]
35 | print(file_name)
36 | if file_name:
37 | self._photo.pixmap().save(file_name)
38 |
39 | def get_image(self):
40 | if self.has_photo():
41 | return self._photo.pixmap().toImage()
42 |
43 | def has_photo(self):
44 | return not self._empty
45 |
46 | def change_image(self, img):
47 | self.update_image(img)
48 | self.fitInView()
49 |
50 | def img_to_pixmap(self, img):
51 | img = cvtColor(img, COLOR_BGR2RGB) # bgr -> rgb
52 | h, w, c = img.shape # 获取图片形状
53 | image = QImage(img, w, h, 3 * w, QImage.Format_RGB888)
54 | return QPixmap.fromImage(image)
55 |
56 | def update_image(self, img):
57 | self._empty = False
58 | self._photo.setPixmap(self.img_to_pixmap(img))
59 |
60 | def fitInView(self, scale=True):
61 | rect = QRectF(self._photo.pixmap().rect())
62 | if not rect.isNull():
63 | self.setSceneRect(rect)
64 |
65 | def wheelEvent(self, event):
66 | if self.has_photo():
67 | if event.angleDelta().y() > 0:
68 | factor = 1.25
69 | self._zoom += 1
70 | else:
71 | factor = 0.8
72 | self._zoom -= 1
73 | if self._zoom > 0:
74 | self.scale(factor, factor)
75 | elif self._zoom == 0:
76 | self.fitInView()
77 | else:
78 | self._zoom = 0
79 |
--------------------------------------------------------------------------------
/custom/listWidgetItems.py:
--------------------------------------------------------------------------------
1 | from PyQt5.QtWidgets import QListWidgetItem
2 | from flags import *
3 |
4 | # 功能区引用
5 | # 几何变换
6 | from function.GeometricTrans.Ratate import ratate
7 | from function.GeometricTrans.ImageCut import cut
8 | from function.GeometricTrans.Mirror import mirror
9 | from function.GeometricTrans.LargeSmall import largeSmall
10 | # 灰度变换
11 | from function.GrayscaleTrans.Reverse import image_reverse
12 | from function.GrayscaleTrans.GammaTrans import gammaTranform
13 | from function.GrayscaleTrans.Binarization import binarization
14 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
15 | # 直方图处理
16 | from function.HistogramTrans.Equalize import hist_equal
17 | from function.HistogramTrans.HistogramMatch import HisgramMatch
18 | # 平滑处理
19 | from function.SmoothingTrans.GaussianFilter import gaussian_filter
20 | from function.SmoothingTrans.MeanFilter import mean_filter
21 | from function.SmoothingTrans.MedianFilter import median_filter
22 | # 锐化处理
23 | from function.SharpenTrans.SobelFilter import sobel_filter
24 | from function.SharpenTrans.Robert import robert
25 | from function.SharpenTrans.Laplacian import laplacian_filter
26 | from function.SharpenTrans.Prewitt import prewitt_filter
27 | # 加性噪声
28 | from function.AddNoise.GasussNoise import gasuss_noise
29 | from function.AddNoise.ImpluseNoise import impluse_noise
30 | from function.AddNoise.RayleighNoise import rayleigh_noise
31 | from function.AddNoise.GammaNoise import gamma_noise
32 | from function.AddNoise.UniformNoise import uniform_noise
33 | from function.AddNoise.ExponentialNoise import exponential_noise
34 | # 频域滤波 | 选择滤波
35 | from function.FrequencyDomainFilter.ButterWorthFilter import butterworthSelectFilter, butterworthFilter
36 | from function.FrequencyDomainFilter.IdealFilter import idealFilter,idealSelectFilter,idealNotchFilter
37 | from function.FrequencyDomainFilter.GaussianFrequencyFilter import GaussianFilter,GaussianSelectFilter
38 | # 彩色图像处理
39 | from function.ColorImageProcess.HSIProcess import hsvProcess, rgb2hsi
40 | from function.ColorImageProcess.RGB2CMY import rgb2cmy
41 | from function.ColorImageProcess.PseudoColorTrans import pseudoColorTrans
42 | # 证件照生成
43 | from function.IdCardPicGenerate.IdCardPicGenerate import idCardPicGenerate
44 |
45 | class MyItem(QListWidgetItem):
46 | def __init__(self, name=None, parent=None):
47 | super(MyItem, self).__init__(name, parent=parent)
48 |
49 | def get_params(self):
50 | protected = [v for v in dir(self) if v.startswith('_') and not v.startswith('__')]
51 | param = {}
52 | for v in protected:
53 | param[v.replace('_', '', 1)] = self.__getattribute__(v)
54 | return param
55 |
56 | def update_params(self, param):
57 | for k, v in param.items():
58 | if '_' + k in dir(self):
59 | self.__setattr__('_' + k, v)
60 |
61 |
62 | class GeometricTransItem(MyItem):
63 | def __init__(self, parent=None):
64 | super(GeometricTransItem, self).__init__(' 几何变换 ', parent=parent)
65 | self._kind = 0
66 | self._rate = 100
67 |
68 | def __call__(self, img):
69 | if self._kind == 0:
70 | img = largeSmall(img,self._rate)
71 | elif self._kind == 1:
72 | img = mirror(img,self._rate)
73 | elif self._kind == 2:
74 | img = ratate(img,self._rate)
75 | elif self._kind == 3:
76 | img = cut(img,self._rate)
77 | # img = cut(img)
78 |
79 | return img
80 |
81 | class GrayingItem(MyItem):
82 | def __init__(self, parent=None):
83 | super(GrayingItem, self).__init__(' 灰度变换 ', parent=parent)
84 | self._kind = RBG2GRAY
85 | self._c_value = 1
86 | self._γ_value = 3.0
87 |
88 | def __call__(self, img):
89 | if self._kind == 0:
90 | img = rgbToGray(img)
91 | elif self._kind == 1:
92 | img = image_reverse(img)
93 | elif self._kind == 2:
94 | img = binarization(img)
95 | elif self._kind == 3:
96 | img = gammaTranform(self._c_value,self._γ_value,img)
97 | return img
98 |
99 |
100 | class EqualizeItem(MyItem):
101 | def __init__(self, parent=None):
102 | super().__init__(' 直方图处理 ', parent=parent)
103 | self._kind = 0
104 |
105 | def __call__(self, img):
106 | if self._kind == 0:
107 | img = hist_equal(img)
108 | elif self._kind == 1:
109 | img = HisgramMatch(img)
110 | return img
111 |
112 |
113 | class FilterItem(MyItem):
114 |
115 | def __init__(self, parent=None):
116 | super().__init__('平滑处理', parent=parent)
117 | self._ksize = 3
118 | self._kind = 0
119 | self._sigma = 1
120 |
121 | def __call__(self, img):
122 | if self._kind == 0:
123 | img = cv2.blur(img, (self._ksize, self._ksize))
124 | # img = mean_filter(img,self._ksize)
125 | elif self._kind == 1:
126 | # cv2实现的中值滤波
127 | img = cv2.medianBlur(img, self._ksize)
128 | # python实现的中值滤波
129 | # img = median_filter(img, self._ksize)
130 | elif self._kind == 2:
131 | # img = cv2.GaussianBlur(img, (self._ksize, self._ksize), self._sigma)
132 | img = gaussian_filter(img,self._ksize,self._sigma)
133 |
134 | return img
135 |
136 |
137 | class SharpenItem(MyItem):
138 | def __init__(self, parent=None):
139 | super().__init__('锐化处理', parent=parent)
140 | self._kind = 0
141 |
142 | def __call__(self, img):
143 | if self._kind == 0:
144 | # python实现
145 | img = sobel_filter(img)
146 | # cv2实现
147 | # img = cv2_sobel(img)
148 | elif self._kind == 1:
149 | img = robert(img)
150 | # cv2实现
151 | # img = cv2_robert(img)
152 | elif self._kind == 2:
153 | img = prewitt_filter(img)
154 | elif self._kind == 3:
155 | img = laplacian_filter(img)
156 | return img
157 |
158 | class AddNoiseItem(MyItem):
159 | def __init__(self, parent=None):
160 | super().__init__('加性噪声', parent=parent)
161 | self._kind = 0
162 | self._scale = 0.1
163 |
164 | def __call__(self, img):
165 | if self._kind == 0:
166 | img = gasuss_noise(img,self._scale)
167 | elif self._kind == 1:
168 | img = rayleigh_noise(img,self._scale)
169 | elif self._kind == 2:
170 | img = gamma_noise(img,self._scale)
171 | elif self._kind == 3:
172 | img = uniform_noise(img,self._scale)
173 | elif self._kind == 4:
174 | img = impluse_noise(img,self._scale)
175 | elif self._kind == 5:
176 | img = exponential_noise(img,self._scale)
177 | return img
178 |
179 | class FrequencyFilterItem(MyItem):
180 | def __init__(self, parent=None):
181 | super().__init__('频域滤波', parent=parent)
182 | self._kind = 0
183 | self._scale = 30
184 | self._n = 1
185 | def __call__(self, img):
186 | if self._kind == 0 or self._kind == 3:
187 | img = idealFilter(img,self._scale,self._kind)
188 | elif self._kind == 1 or self._kind == 4:
189 | img = butterworthFilter(img,self._scale,self._n,self._kind)
190 | elif self._kind == 2 or self._kind == 5:
191 | img = GaussianFilter(img,self._scale,self._kind)
192 | return img
193 |
194 |
195 | class SelectFilterItem(MyItem):
196 | def __init__(self, parent=None):
197 | super().__init__('选择滤波', parent=parent)
198 | self._kind = 0
199 | self._scale = 30
200 | self._n = 1
201 | self._W = 10
202 | def __call__(self, img):
203 | if self._kind == 0 or self._kind == 3:
204 | img = idealSelectFilter(img,self._scale,self._W,self._kind)
205 | elif self._kind == 1 or self._kind == 4:
206 | img = butterworthSelectFilter(img,self._scale,self._n,self._W,self._kind)
207 | elif self._kind == 2 or self._kind == 5:
208 | img = GaussianSelectFilter(img,self._scale,self._W,self._kind)
209 | elif self._kind == 6 or self._kind == 7:
210 | img = idealNotchFilter(img,self._scale,self._kind)
211 | return img
212 |
213 | class ColorImageProcessItem(MyItem):
214 | def __init__(self, parent=None):
215 | super().__init__('彩色图像处理', parent=parent)
216 | self._kind = 0
217 | self._H = 100
218 | self._S = 100
219 | self._V = 100
220 | self._color_kind = 0
221 |
222 | def __call__(self, img):
223 | if self._kind == 0:
224 | img = hsvProcess(img,self._H,self._S,self._V)
225 | elif self._kind == 1:
226 | img = rgb2cmy(img,self._H,self._S,self._V)
227 | elif self._kind == 2:
228 | img = rgb2hsi(img,self._H,self._S,self._V)
229 | elif self._kind == 3:
230 | img = pseudoColorTrans(img,self._H,self._S,self._V,self._color_kind)
231 | return img
232 |
233 |
234 | class IdCardPicGenerateItem(MyItem):
235 | def __init__(self, parent=None):
236 | super().__init__('证件照生成', parent=parent)
237 | self._kind = 0
238 | self._H = 100
239 | self._S = 100
240 | self._V = 100
241 | def __call__(self, img):
242 | img = idCardPicGenerate(img, self._kind)
243 | return img
--------------------------------------------------------------------------------
/custom/listWidgets.py:
--------------------------------------------------------------------------------
1 | from PyQt5.QtCore import Qt
2 | from PyQt5.QtGui import QCursor
3 | from PyQt5.QtWidgets import QListWidget, QListView, QAbstractItemView, QAction, QMenu
4 |
5 | from config import items
6 |
7 |
8 | class MyListWidget(QListWidget):
9 | def __init__(self, parent=None):
10 | super().__init__(parent=parent)
11 | self.mainwindow = parent
12 | self.setDragEnabled(True)
13 | # 选中不显示虚线
14 | # self.setEditTriggers(QAbstractItemView.NoEditTriggers)
15 | self.setFocusPolicy(Qt.NoFocus)
16 |
17 |
18 | class UsedListWidget(MyListWidget):
19 | def __init__(self, parent=None):
20 | super().__init__(parent=parent)
21 | self.setAcceptDrops(True) # 激活组件的拖拽事件
22 | self.setFlow(QListView.TopToBottom) # 设置列表方向(表示数据项从上至下排列)
23 | self.setDefaultDropAction(Qt.MoveAction) # 设置拖放为移动而不是复制一个
24 | self.setDragDropMode(QAbstractItemView.InternalMove) # 设置拖放模式, 内部拖放
25 | self.itemClicked.connect(self.show_attr)
26 | self.setMinimumWidth(200)
27 |
28 | self.move_item = None
29 |
30 | def contextMenuEvent(self, e):
31 | # 右键菜单事件
32 | item = self.itemAt(self.mapFromGlobal(QCursor.pos()))
33 | if not item: return # 判断是否是空白区域
34 | menu = QMenu()
35 | delete_action = QAction('删除', self)
36 | delete_action.triggered.connect(lambda: self.delete_item(item)) # 传递额外值
37 | menu.addAction(delete_action)
38 | menu.exec(QCursor.pos())
39 |
40 | def delete_item(self, item):
41 | # 删除操作
42 | self.takeItem(self.row(item))
43 | self.mainwindow.update_image() # 更新frame
44 | self.mainwindow.dock_attr.close()
45 |
46 | def dropEvent(self, event):
47 | super().dropEvent(event)
48 | self.mainwindow.update_image()
49 |
50 | def show_attr(self):
51 | item = self.itemAt(self.mapFromGlobal(QCursor.pos()))
52 | if not item: return
53 | param = item.get_params() # 获取当前item的属性
54 | if type(item) in items:
55 | index = items.index(type(item)) # 获取item对应的table索引
56 | self.mainwindow.stackedWidget.setCurrentIndex(index)
57 | self.mainwindow.stackedWidget.currentWidget().update_params(param) # 更新对应的table
58 | self.mainwindow.dock_attr.show()
59 |
60 |
61 | class FuncListWidget(MyListWidget):
62 | def __init__(self, parent=None):
63 | super().__init__(parent=parent)
64 | self.setFixedHeight(64)
65 | self.setFlow(QListView.LeftToRight) # 设置列表方向
66 | self.setViewMode(QListView.IconMode) # 设置列表模式
67 | # self.setViewMode(QListView.ViewMode)
68 | self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 关掉滑动条
69 | self.setAcceptDrops(False)
70 | for itemType in items:
71 | self.addItem(itemType())
72 | self.itemClicked.connect(self.add_used_function)
73 |
74 | def add_used_function(self):
75 | func_item = self.currentItem()
76 | if type(func_item) in items:
77 | use_item = type(func_item)()
78 | self.mainwindow.useListWidget.addItem(use_item)
79 | self.mainwindow.update_image()
80 |
81 | def enterEvent(self, event):
82 | self.setCursor(Qt.PointingHandCursor)
83 |
84 | def leaveEvent(self, event):
85 | self.setCursor(Qt.ArrowCursor)
86 | self.setCurrentRow(-1) # 取消选中状态
87 |
--------------------------------------------------------------------------------
/custom/stackedWidget.py:
--------------------------------------------------------------------------------
1 | from PyQt5.QtWidgets import QStackedWidget
2 |
3 | from config import tables
4 |
5 |
6 | class StackedWidget(QStackedWidget):
7 | def __init__(self, parent):
8 | super().__init__(parent=parent)
9 | for table in tables:
10 | self.addWidget(table(parent=parent))
11 | self.setMinimumWidth(200)
12 |
--------------------------------------------------------------------------------
/custom/tableWidget.py:
--------------------------------------------------------------------------------
1 | from PyQt5.QtCore import Qt
2 | from PyQt5.QtWidgets import QTableWidget, QAbstractItemView, QHeaderView, QSpinBox, QDoubleSpinBox, QCheckBox, \
3 | QComboBox, QWidget, QTableWidgetItem, QSlider, QLabel
4 |
5 |
6 | class TableWidget(QTableWidget):
7 | def __init__(self, parent=None):
8 | super(TableWidget, self).__init__(parent=parent)
9 | self.mainwindow = parent
10 | self.setShowGrid(True) # 显示网格
11 | self.setAlternatingRowColors(True) # 隔行显示颜色
12 | self.setEditTriggers(QAbstractItemView.NoEditTriggers)
13 | self.horizontalHeader().setVisible(False)
14 | self.verticalHeader().setVisible(False)
15 | self.horizontalHeader().sectionResizeMode(QHeaderView.Stretch)
16 | self.verticalHeader().sectionResizeMode(QHeaderView.Stretch)
17 | self.horizontalHeader().setStretchLastSection(True)
18 | self.setFocusPolicy(Qt.NoFocus)
19 |
20 | def signal_connect(self):
21 | for spinbox in self.findChildren(QSpinBox):
22 | spinbox.valueChanged.connect(self.update_item)
23 | for doublespinbox in self.findChildren(QDoubleSpinBox):
24 | doublespinbox.valueChanged.connect(self.update_item)
25 | for combox in self.findChildren(QComboBox):
26 | combox.currentIndexChanged.connect(self.update_item)
27 | for checkbox in self.findChildren(QCheckBox):
28 | checkbox.stateChanged.connect(self.update_item)
29 | for qslider in self.findChildren(QSlider):
30 | qslider.valueChanged.connect(self.update_item)
31 |
32 | def update_item(self):
33 | param = self.get_params()
34 | self.mainwindow.useListWidget.currentItem().update_params(param)
35 | self.mainwindow.update_image()
36 |
37 | def update_params(self, param=None):
38 | for key in param.keys():
39 | box = self.findChild(QWidget, name=key)
40 | if isinstance(box, QSpinBox) or isinstance(box, QDoubleSpinBox):
41 | box.setValue(param[key])
42 | elif isinstance(box, QComboBox):
43 | box.setCurrentIndex(param[key])
44 | elif isinstance(box, QCheckBox):
45 | box.setChecked(param[key])
46 | elif isinstance(box, QSlider):
47 | box.setValue(param[key])
48 |
49 | def get_params(self):
50 | param = {}
51 | for spinbox in self.findChildren(QSpinBox):
52 | param[spinbox.objectName()] = spinbox.value()
53 | for doublespinbox in self.findChildren(QDoubleSpinBox):
54 | param[doublespinbox.objectName()] = doublespinbox.value()
55 | for combox in self.findChildren(QComboBox):
56 | param[combox.objectName()] = combox.currentIndex()
57 | for combox in self.findChildren(QCheckBox):
58 | param[combox.objectName()] = combox.isChecked()
59 | for qslider in self.findChildren(QSlider):
60 | param[qslider.objectName()] = qslider.value()
61 | return param
62 |
63 |
64 | class GeometricTransTableWight(TableWidget):
65 | def __init__(self, parent=None):
66 | super(GeometricTransTableWight, self).__init__(parent=parent)
67 | self.kind_comBox = QComboBox()
68 | self.kind_comBox.addItems(['放大|缩小','图像镜像','图像旋转','图像裁剪'])
69 | self.kind_comBox.setObjectName('kind')
70 |
71 | self.setColumnCount(2)
72 | self.setRowCount(2)
73 |
74 |
75 | # self.rate_value_doubleBox = QDoubleSpinBox()
76 | # self.rate_value_doubleBox.setObjectName('rate')
77 | # self.rate_value_doubleBox.setDecimals(1)
78 | # self.rate_value_spinBox.setMinimum()
79 | # self.rate_value_doubleBox.setSingleStep(0.1)
80 | self.rate_value_spinBox = QSpinBox()
81 | self.rate_value_spinBox.setObjectName('rate')
82 | self.rate_value_spinBox.setRange(0,360)
83 | self.rate_value_spinBox.setSingleStep(10)
84 | # self.rate_value_spinBox.setSuffix("%")
85 | self.setItem(0, 0, QTableWidgetItem('类型'))
86 | self.setCellWidget(0, 1, self.kind_comBox)
87 | self.setItem(1, 0, QTableWidgetItem('比例%|角度°'))
88 | self.setCellWidget(1, 1, self.rate_value_spinBox)
89 | self.signal_connect()
90 |
91 | class GrayingTableWidget(TableWidget):
92 | def __init__(self, parent=None):
93 | super(GrayingTableWidget, self).__init__(parent=parent)
94 |
95 | self.kind_comBox = QComboBox()
96 | self.kind_comBox.addItems(['灰度化', '图像反转', '二值化','幂律变换'])
97 | self.kind_comBox.setObjectName('kind')
98 |
99 | self.c_value_spinBox = QSpinBox()
100 | self.c_value_spinBox.setObjectName('c_value')
101 | self.c_value_spinBox.setMinimum(1)
102 | self.c_value_spinBox.setSingleStep(1)
103 |
104 | self.γ_value_spinBox = QSpinBox()
105 | self.γ_value_spinBox.setObjectName('γ_value')
106 | self.γ_value_spinBox.setMinimum(1)
107 | self.γ_value_spinBox.setSingleStep(1)
108 |
109 | self.setColumnCount(2)
110 | self.setRowCount(3)
111 | self.setItem(0, 0, QTableWidgetItem('类型'))
112 | self.setCellWidget(0, 1, self.kind_comBox)
113 | self.setItem(1, 0, QTableWidgetItem('c值(幂律变换)'))
114 | self.setCellWidget(1, 1, self.c_value_spinBox)
115 | self.setItem(2, 0, QTableWidgetItem('γ值(幂律变换)'))
116 | self.setCellWidget(2, 1, self.γ_value_spinBox)
117 |
118 | self.signal_connect()
119 |
120 | class EqualizeTableWidget(TableWidget):
121 | def __init__(self, parent=None):
122 | super(EqualizeTableWidget, self).__init__(parent=parent)
123 | self.kind_comBox = QComboBox()
124 | self.kind_comBox.addItems(['直方图均衡化', '直方图匹配'])
125 | self.kind_comBox.setObjectName('kind')
126 | self.setColumnCount(2)
127 | self.setRowCount(1)
128 | self.setItem(0, 0, QTableWidgetItem('类型'))
129 | self.setCellWidget(0, 1, self.kind_comBox)
130 | self.signal_connect()
131 |
132 |
133 | class FilterTabledWidget(TableWidget):
134 | def __init__(self, parent=None):
135 | super(FilterTabledWidget, self).__init__(parent=parent)
136 |
137 | self.kind_comBox = QComboBox()
138 | self.kind_comBox.addItems(['均值滤波', '中值滤波','高斯滤波'])
139 | self.kind_comBox.setObjectName('kind')
140 |
141 |
142 | self.ksize_spinBox = QSpinBox()
143 | self.ksize_spinBox.setObjectName('ksize')
144 | self.ksize_spinBox.setMinimum(1)
145 | self.ksize_spinBox.setSingleStep(2)
146 |
147 | self.sigma_DoubleBox = QDoubleSpinBox()
148 | self.sigma_DoubleBox.setObjectName('sigma')
149 | self.sigma_DoubleBox.setMinimum(1)
150 | self.sigma_DoubleBox.setSingleStep(1)
151 |
152 | self.setColumnCount(2)
153 | self.setRowCount(3)
154 | self.setItem(0, 0, QTableWidgetItem('类型'))
155 | self.setCellWidget(0, 1, self.kind_comBox)
156 | self.setItem(1, 0, QTableWidgetItem('size'))
157 | self.setCellWidget(1, 1, self.ksize_spinBox)
158 | self.setItem(2, 0, QTableWidgetItem('sigma(高斯滤波)'))
159 | self.setCellWidget(2, 1, self.sigma_DoubleBox)
160 |
161 | self.signal_connect()
162 |
163 |
164 | class SharpenItemTableWidget(TableWidget):
165 | def __init__(self, parent=None):
166 | super(SharpenItemTableWidget, self).__init__(parent=parent)
167 | self.kind_comBox = QComboBox()
168 | self.kind_comBox.addItems(['sobel算子','robert算子','prewitt算子','laplacian算子'])
169 | self.kind_comBox.setObjectName('kind')
170 |
171 | self.setColumnCount(2)
172 | self.setRowCount(1)
173 | self.setItem(0, 0, QTableWidgetItem('类型'))
174 | self.setCellWidget(0, 1, self.kind_comBox)
175 | self.signal_connect()
176 |
177 | class AddNoiseItemTableWidget(TableWidget):
178 | def __init__(self, parent=None):
179 | super(AddNoiseItemTableWidget, self).__init__(parent=parent)
180 | self.kind_comBox = QComboBox()
181 | self.kind_comBox.addItems(['高斯噪声','瑞利噪声','伽马噪声','均匀噪声','椒盐噪声','指数噪声'])
182 | self.kind_comBox.setObjectName('kind')
183 |
184 | self.ksize_DoubleBox = QDoubleSpinBox()
185 | self.ksize_DoubleBox.setMinimum(0)
186 | self.ksize_DoubleBox.setSingleStep(0.1)
187 | self.ksize_DoubleBox.setObjectName('scale')
188 |
189 | self.setColumnCount(2)
190 | self.setRowCount(2)
191 | self.setItem(0, 0, QTableWidgetItem('噪声类型'))
192 | self.setCellWidget(0, 1, self.kind_comBox)
193 | self.setItem(1, 0, QTableWidgetItem('噪声比例'))
194 | self.setCellWidget(1, 1, self.ksize_DoubleBox)
195 | self.signal_connect()
196 |
197 |
198 | class FrequencyFilterTabledWidget(TableWidget):
199 | def __init__(self, parent=None):
200 | super(FrequencyFilterTabledWidget, self).__init__(parent=parent)
201 | self.kind_comBox = QComboBox()
202 | self.kind_comBox.addItems(['理想低通滤波','巴特沃思低通滤波','高斯低通滤波','理想高通滤波','巴特沃思高通滤波','高斯高通滤波'])
203 | self.kind_comBox.setObjectName('kind')
204 | self.ksize_SpinBox = QSpinBox()
205 | self.ksize_SpinBox.setMinimum(10)
206 | self.ksize_SpinBox.setSingleStep(10)
207 | self.ksize_SpinBox.setObjectName('scale')
208 | self.n_Spinbox = QSpinBox()
209 | self.n_Spinbox.setMinimum(1)
210 | self.n_Spinbox.setSingleStep(1)
211 | self.n_Spinbox.setObjectName('n')
212 |
213 | self.setColumnCount(2)
214 | self.setRowCount(3)
215 | self.setItem(0, 0, QTableWidgetItem('滤波类型'))
216 | self.setCellWidget(0, 1, self.kind_comBox)
217 | self.setItem(1, 0, QTableWidgetItem('半径r'))
218 | self.setCellWidget(1, 1, self.ksize_SpinBox)
219 | self.setItem(2,0,QTableWidgetItem('阶数n'))
220 | self.setCellWidget(2,1,self.n_Spinbox)
221 | self.signal_connect()
222 |
223 |
224 | class SelectFilterTabledWidget(TableWidget):
225 | def __init__(self, parent=None):
226 | super(SelectFilterTabledWidget, self).__init__(parent=parent)
227 | self.kind_comBox = QComboBox()
228 | self.kind_comBox.addItems(['理想带阻滤波', '巴特沃思带阻滤波', '高斯带阻滤波', '理想带通滤波', '巴特沃思带通滤波', '高斯带通滤波','理想带阻陷波','理想带通陷波'])
229 | self.kind_comBox.setObjectName('kind')
230 | self.ksize_SpinBox = QSpinBox()
231 | self.ksize_SpinBox.setMinimum(0)
232 | self.ksize_SpinBox.setMaximum(300)
233 | self.ksize_SpinBox.setSingleStep(10)
234 | self.ksize_SpinBox.setObjectName('scale')
235 | self.W_Spinbox = QSpinBox()
236 | self.W_Spinbox.setMinimum(0)
237 | self.W_Spinbox.setMaximum(500)
238 | self.W_Spinbox.setSingleStep(10)
239 | self.W_Spinbox.setObjectName('W')
240 | self.n_Spinbox = QSpinBox()
241 | self.n_Spinbox.setMinimum(1)
242 | self.n_Spinbox.setSingleStep(1)
243 | self.n_Spinbox.setObjectName('n')
244 |
245 | self.setColumnCount(2)
246 | self.setRowCount(4)
247 | self.setItem(0, 0, QTableWidgetItem('滤波类型'))
248 | self.setCellWidget(0, 1, self.kind_comBox)
249 | self.setItem(1, 0, QTableWidgetItem('半径r'))
250 | self.setCellWidget(1, 1, self.ksize_SpinBox)
251 | self.setItem(2, 0, QTableWidgetItem('带宽W'))
252 | self.setCellWidget(2, 1, self.W_Spinbox)
253 | self.setItem(3, 0, QTableWidgetItem('阶数n'))
254 | self.setCellWidget(3, 1, self.n_Spinbox)
255 | self.signal_connect()
256 |
257 | class ColorImageProcessTabledWidget(TableWidget):
258 | def __init__(self, parent=None):
259 | super(ColorImageProcessTabledWidget, self).__init__(parent=parent)
260 | self.kind_comBox = QComboBox()
261 | self.kind_comBox.addItems(['RGB模型', 'CMY模型','HSI模型','伪彩色变换'])
262 | # self.kind_comBox.addItems(['彩色模型', '伪彩色变换', '真彩色变换'])
263 | self.kind_comBox.setObjectName('kind')
264 |
265 | # self.H_qslider = QSlider(Qt.Horizontal)
266 | self.H_qslider = MyQSlider()
267 | self.H_qslider.setOrientation(Qt.Horizontal)
268 | self.H_qslider.setMinimum(0)
269 | self.H_qslider.setMaximum(150)
270 | self.H_qslider.setSingleStep(10)
271 | self.H_qslider.setTickPosition(QSlider.TicksBelow)
272 | self.H_qslider.setTickInterval(10)
273 | self.H_qslider.setObjectName('H')
274 |
275 | # self.S_qslider = QSlider(Qt.Horizontal)
276 | self.S_qslider = MyQSlider()
277 | self.S_qslider.setOrientation(Qt.Horizontal)
278 | self.S_qslider.setMinimum(0)
279 | self.S_qslider.setMaximum(150)
280 | self.S_qslider.setSingleStep(10)
281 | self.S_qslider.setTickPosition(QSlider.TicksBelow)
282 | self.S_qslider.setTickInterval(10)
283 | self.S_qslider.setObjectName('S')
284 |
285 | # self.V_qslider = QSlider(Qt.Horizontal)
286 | self.V_qslider = MyQSlider()
287 | self.V_qslider.setOrientation(Qt.Horizontal)
288 | self.V_qslider.setMinimum(0)
289 | self.V_qslider.setMaximum(150)
290 | self.V_qslider.setSingleStep(10)
291 | self.V_qslider.setTickPosition(QSlider.TicksBelow)
292 | self.V_qslider.setTickInterval(10)
293 | self.V_qslider.setObjectName('V')
294 |
295 | self.pseudoColor_comBox = QComboBox()
296 | self.pseudoColor_comBox.addItems(['COLORMAP_AUTUMN', 'COLORMAP_BONE', 'COLORMAP_JET', 'COLORMAP_WINTER', 'COLORMAP_RAINBOW','COLORMAP_OCEAN','COLORMAP_SUMMER','COLORMAP_SPRING','COLORMAP_COOL','COLORMAP_HSV','COLORMAP_PINK','COLORMAP_HOT'])
297 | # self.kind_comBox.addItems(['彩色模型', '伪彩色变换', '真彩色变换'])
298 | self.pseudoColor_comBox.setObjectName('color_kind')
299 |
300 |
301 | self.setColumnCount(2)
302 | self.setRowCount(5)
303 | self.setItem(0, 0, QTableWidgetItem('颜色变换'))
304 | self.setCellWidget(0, 1, self.kind_comBox)
305 | self.setItem(1, 0, QTableWidgetItem('B通道'))
306 | self.setCellWidget(1, 1, self.H_qslider)
307 | self.setItem(2, 0, QTableWidgetItem('G通道'))
308 | self.setCellWidget(2, 1, self.S_qslider)
309 | self.setItem(3, 0, QTableWidgetItem('R通道'))
310 | self.setCellWidget(3, 1, self.V_qslider)
311 | self.setItem(4, 0, QTableWidgetItem('伪彩色类型'))
312 | self.setCellWidget(4, 1, self.pseudoColor_comBox)
313 |
314 | self.signal_connect()
315 |
316 |
317 | class IdCardPicGenerateTabledWidget(TableWidget):
318 | def __init__(self, parent=None):
319 | super(IdCardPicGenerateTabledWidget, self).__init__(parent=parent)
320 | self.kind_comBox = QComboBox()
321 | self.kind_comBox.addItems(['蓝底', '红底','白底'])
322 | self.kind_comBox.setObjectName('kind')
323 | self.setColumnCount(2)
324 | self.setRowCount(1)
325 | self.setItem(0, 0, QTableWidgetItem('证件照合成'))
326 | self.setCellWidget(0, 1, self.kind_comBox)
327 | self.signal_connect()
328 |
329 | class MyQSlider(QSlider):
330 | def __init__(self,parent=None,*args,**kwargs):
331 | super().__init__(parent,*args,**kwargs)
332 | label = QLabel(self)
333 | self.label = label
334 | label.setText('100')
335 | label.setStyleSheet('background-color:cyan;color:red')
336 | label.hide()
337 |
338 | def mousePressEvent(self, evt):
339 | super().mousePressEvent(evt)
340 | y = (1-((self.value()-self.minimum())/(self.maximum()-self.minimum())))*(self.height()-self.label.height())
341 | x = (self.width()-self.label.width())/2
342 | self.label.move(x,y)
343 | self.label.show()
344 | self.label.setText(str(self.value()))
345 |
346 | def mouseMoveEvent(self, evt):
347 | super().mouseMoveEvent(evt)
348 | y = (1-((self.value()-self.minimum())/(self.maximum()-self.minimum())))*(self.height()-self.label.height())
349 | x = (self.width()-self.label.width())/2
350 | self.label.move(x,y)
351 | self.label.setText(str(self.value()))
352 | self.label.adjustSize()
353 |
354 | def mouseReleaseEvent(self, evt):
355 | super().mouseReleaseEvent(evt)
356 | self.label.hide()
357 |
--------------------------------------------------------------------------------
/custom/treeView.py:
--------------------------------------------------------------------------------
1 | from cv2 import imdecode
2 | import numpy as np
3 | from PyQt5.QtCore import Qt
4 | from PyQt5.QtWidgets import QTreeView, QDockWidget, QFileSystemModel
5 |
6 |
7 | class FileSystemTreeView(QTreeView, QDockWidget):
8 | def __init__(self, parent=None):
9 | super().__init__(parent=parent)
10 | self.mainwindow = parent
11 | self.fileSystemModel = QFileSystemModel()
12 | self.fileSystemModel.setRootPath('.')
13 | self.setModel(self.fileSystemModel)
14 | # 隐藏size,date等列
15 | self.setColumnWidth(0, 200)
16 | self.setColumnHidden(1, True)
17 | self.setColumnHidden(2, True)
18 | self.setColumnHidden(3, True)
19 | # 不显示标题栏
20 | self.header().hide()
21 | # 设置动画
22 | self.setAnimated(True)
23 | # 选中不显示虚线
24 | self.setFocusPolicy(Qt.NoFocus)
25 | self.doubleClicked.connect(self.select_image)
26 | self.setMinimumWidth(200)
27 |
28 | def select_image(self, file_index):
29 | file_name = self.fileSystemModel.filePath(file_index)
30 | if file_name.endswith(('.jpg', '.png', '.bmp')):
31 | src_img = imdecode(np.fromfile(file_name, dtype=np.uint8), -1)
32 | self.mainwindow.change_image(src_img)
33 |
34 |
--------------------------------------------------------------------------------
/flags.py:
--------------------------------------------------------------------------------
1 | import cv2
2 |
3 | GRAYING_STACKED_WIDGET = 0
4 | FILTER_STACKED_WIDGET = 1
5 | MORPH_STACKED_WIDGET = 2
6 | GRAD_STACKED_WIDGET = 3
7 | THRESH_STACKED_WIDGET = 4
8 | EDGE_STACKED_WIDGET = 5
9 |
10 | # 功能区
11 |
12 | BGR2GRAY_COLOR = 0
13 | GRAY2BGR_COLOR = 1
14 | COLOR = {
15 | BGR2GRAY_COLOR: cv2.COLOR_BGR2GRAY,
16 | GRAY2BGR_COLOR: cv2.COLOR_GRAY2BGR
17 | }
18 |
19 | # 图像灰度处理
20 | RBG2GRAY = 0
21 | REVERSE = 1
22 | PLTRANS = 2
23 | Binarization = 3
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | MEAN_FILTER = 0
32 | GAUSSIAN_FILTER = 1
33 | MEDIAN_FILTER = 2
34 |
35 | ERODE_MORPH_OP = 0
36 | DILATE_MORPH_OP = 1
37 | OPEN_MORPH_OP = 2
38 | CLOSE_MORPH_OP = 3
39 | GRADIENT_MORPH_OP = 4
40 | TOPHAT_MORPH_OP = 5
41 | BLACKHAT_MORPH_OP = 6
42 |
43 | MORPH_OP = {
44 | ERODE_MORPH_OP: cv2.MORPH_ERODE,
45 | DILATE_MORPH_OP: cv2.MORPH_DILATE,
46 | OPEN_MORPH_OP: cv2.MORPH_OPEN,
47 | CLOSE_MORPH_OP: cv2.MORPH_CLOSE,
48 | GRADIENT_MORPH_OP: cv2.MORPH_GRADIENT,
49 | TOPHAT_MORPH_OP: cv2.MORPH_TOPHAT,
50 | BLACKHAT_MORPH_OP: cv2.MORPH_BLACKHAT
51 | }
52 |
53 | RECT_MORPH_SHAPE = 0
54 | CROSS_MORPH_SHAPE = 1
55 | ELLIPSE_MORPH_SHAPE = 2
56 |
57 | MORPH_SHAPE = {
58 | RECT_MORPH_SHAPE: cv2.MORPH_RECT,
59 | CROSS_MORPH_SHAPE: cv2.MORPH_CROSS,
60 | ELLIPSE_MORPH_SHAPE: cv2.MORPH_ELLIPSE
61 | }
62 |
63 | SOBEL_GRAD = 0
64 | SCHARR_GRAD = 1
65 | LAPLACIAN_GRAD = 2
66 |
67 | BINARY_THRESH_METHOD = 0
68 | BINARY_INV_THRESH_METHOD = 1
69 | TRUNC_THRESH_METHOD = 2
70 | TOZERO_THRESH_METHOD = 3
71 | TOZERO_INV_THRESH_METHOD = 4
72 | OTSU_THRESH_METHOD = 5
73 | THRESH_METHOD = {
74 | BINARY_THRESH_METHOD: cv2.THRESH_BINARY, # 0
75 | BINARY_INV_THRESH_METHOD: cv2.THRESH_BINARY_INV, # 1
76 | TRUNC_THRESH_METHOD: cv2.THRESH_TRUNC, # 2
77 | TOZERO_THRESH_METHOD: cv2.THRESH_TOZERO, # 3
78 | TOZERO_INV_THRESH_METHOD: cv2.THRESH_TOZERO_INV, # 4
79 | OTSU_THRESH_METHOD: cv2.THRESH_OTSU # 5
80 | }
81 |
82 | EXTERNAL_CONTOUR_MODE = 0
83 | LIST_CONTOUR_MODE = 1
84 | CCOMP_CONTOUR_MODE = 2
85 | TREE_CONTOUR_MODE = 3
86 | CONTOUR_MODE = {
87 | EXTERNAL_CONTOUR_MODE: cv2.RETR_EXTERNAL,
88 | LIST_CONTOUR_MODE: cv2.RETR_LIST,
89 | CCOMP_CONTOUR_MODE: cv2.RETR_CCOMP,
90 | TREE_CONTOUR_MODE: cv2.RETR_TREE
91 | }
92 |
93 | NONE_CONTOUR_METHOD = 0
94 | SIMPLE_CONTOUR_METHOD = 1
95 | CONTOUR_METHOD = {
96 | NONE_CONTOUR_METHOD: cv2.CHAIN_APPROX_NONE,
97 | SIMPLE_CONTOUR_METHOD: cv2.CHAIN_APPROX_SIMPLE
98 | }
99 |
100 | NORMAL_CONTOUR = 0
101 | RECT_CONTOUR = 1
102 | MINRECT_CONTOUR = 2
103 | MINCIRCLE_CONTOUR = 3
104 |
105 |
106 | # 均衡化
107 | BLUE_CHANNEL = 0
108 | GREEN_CHANNEL = 1
109 | RED_CHANNEL = 2
110 | ALL_CHANNEL = 3
111 |
112 |
113 | # 伪彩色变换
114 | COLORMAP_AUTUMN = 0
115 | COLORMAP_BONE = 1
116 | COLORMAP_JET = 2
117 | COLORMAP_WINTER = 3
118 | COLORMAP_RAINBOW = 4
119 | COLORMAP_OCEAN = 5
120 | COLORMAP_SUMMER = 6
121 | COLORMAP_SPRING = 7
122 | COLORMAP_COOL = 8
123 | COLORMAP_HSV = 9
124 | COLORMAP_PINK = 10
125 | COLORMAP_HOT = 11
--------------------------------------------------------------------------------
/function/AddNoise/ExponentialNoise.py:
--------------------------------------------------------------------------------
1 | # import numpy as np
2 | from numpy import array,random,clip,uint8
3 |
4 | def exponential_noise(image, scale = 0.1):
5 | '''
6 | 指数噪声
7 | :param scale:指数值
8 | '''
9 | image = array(image/255, dtype=float)
10 | noise = random.exponential(scale,image.shape)
11 | out = image + noise
12 | if out.min() < 0:
13 | low_clip = -1.
14 | else:
15 | low_clip = 0.
16 | out = clip(out, low_clip, 1.0)
17 | out = uint8(out*255)
18 | return out
--------------------------------------------------------------------------------
/function/AddNoise/GammaNoise.py:
--------------------------------------------------------------------------------
1 | # import numpy as np
2 | # import cv2
3 | from numpy import array,random,clip,uint8
4 |
5 | def gamma_noise(image, var=0.1):
6 | '''
7 | 伽马噪声
8 | :param var: 方差
9 | '''
10 | image = array(image/255, dtype=float)
11 | # 伽马分布
12 | noise = random.gamma(3,var ** 0.5, image.shape)
13 | out = image + noise
14 | if out.min() < 0:
15 | low_clip = -1.
16 | else:
17 | low_clip = 0.
18 | out = clip(out, low_clip, 1.0)
19 | out = uint8(out*255)
20 | return out
--------------------------------------------------------------------------------
/function/AddNoise/GasussNoise.py:
--------------------------------------------------------------------------------
1 | # import numpy as np
2 | # import cv2
3 | from numpy import array,random,clip,uint8
4 |
5 | def gasuss_noise(image, var=0.1, mean=0):
6 | '''
7 | 添加高斯噪声
8 | mean : 均值
9 | var : 方差
10 | '''
11 | image = array(image/255, dtype=float)
12 | # 高斯分布
13 | noise = random.normal(mean, var ** 0.5, image.shape)
14 | out = image + noise
15 | if out.min() < 0:
16 | low_clip = -1.
17 | else:
18 | low_clip = 0.
19 | out = clip(out, low_clip, 1.0)
20 | out = uint8(out*255)
21 | return out
22 |
--------------------------------------------------------------------------------
/function/AddNoise/ImpluseNoise.py:
--------------------------------------------------------------------------------
1 | from random import random
2 | from numpy import zeros,uint8,random
3 | import cv2
4 |
5 | def impluse_noise(image,prob=0.1):
6 | '''
7 | 添加椒盐噪声
8 | prob:噪声比例
9 | '''
10 | output = zeros(image.shape,uint8)
11 | thres = 1 - prob
12 | for i in range(image.shape[0]):
13 | for j in range(image.shape[1]):
14 | rdn = random.random()
15 | if rdn < prob:
16 | output[i][j] = 0
17 | elif rdn > thres:
18 | output[i][j] = 255
19 | else:
20 | output[i][j] = image[i][j]
21 | return output
22 |
23 |
--------------------------------------------------------------------------------
/function/AddNoise/RayleighNoise.py:
--------------------------------------------------------------------------------
1 | # import numpy as np
2 | from numpy import array,clip,uint8
3 | from numpy.random import rayleigh
4 | def rayleigh_noise(image,var=0.1):
5 | '''
6 | 添加瑞利噪声
7 | var : 方差
8 | '''
9 | image = array(image/255, dtype=float)
10 | # 瑞利分布
11 | noise = rayleigh(var ** 0.5, image.shape)
12 | out = image + noise
13 | if out.min() < 0:
14 | low_clip = -1.
15 | else:
16 | low_clip = 0.
17 | out = clip(out, low_clip, 1.0)
18 | out = uint8(out*255)
19 | return out
20 |
--------------------------------------------------------------------------------
/function/AddNoise/UniformNoise.py:
--------------------------------------------------------------------------------
1 | from numpy import array,clip,uint8
2 | from numpy.random import uniform
3 | def uniform_noise(image,hight=1.0,low=0.0):
4 | '''
5 | 均匀噪声
6 | :param hight:采样上界
7 | :param low:采样下界
8 | '''
9 | image = array(image/255, dtype=float)
10 | # 均匀分布
11 | noise = uniform(low,hight,image.shape)
12 | out = image + noise
13 | if out.min() < 0:
14 | low_clip = -1.
15 | else:
16 | low_clip = 0.
17 | out = clip(out, low_clip, 1.0)
18 | out = uint8(out*255)
19 | return out
20 |
--------------------------------------------------------------------------------
/function/AddNoise/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__init__.py
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/ExponentialNoise.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/ExponentialNoise.cpython-37.pyc
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/GammaNoise.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/GammaNoise.cpython-37.pyc
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/GasussNoise.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/GasussNoise.cpython-37.pyc
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/ImpluseNoise.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/ImpluseNoise.cpython-37.pyc
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/RayleighNoise.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/RayleighNoise.cpython-37.pyc
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/UniformNoise.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/UniformNoise.cpython-37.pyc
--------------------------------------------------------------------------------
/function/AddNoise/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/AddNoise/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/ColorImageProcess/HSIProcess.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 |
4 |
5 | def hsvProcess(img,h_value,s_value,v_value):
6 | '''
7 | 调节r,g,b的成分比例
8 | :param img:
9 | :param h_value: b的比例
10 | :param s_value: g的比例
11 | :param v_value: r的比例
12 | :return:
13 | '''
14 | h_value = float(h_value/100)
15 | s_value = float(s_value/100)
16 | v_value = float(v_value/100)
17 | if img.shape[2] == 4:
18 | img = cv2.cvtColor(img, cv2.COLOR_RGBA2RGB)
19 | H, S, V = cv2.split(img) # (b,g,r)
20 | new_pic = cv2.merge([np.uint8(H * h_value), np.uint8(S * s_value), np.uint8(V * v_value)])
21 | return new_pic
22 |
23 |
24 |
25 |
26 | def rgb2hsi(rgb_img,h_value,s_value,i_value):
27 | h_value = float(h_value / 100)
28 | s_value = float(s_value / 100)
29 | i_value = float(i_value / 100)
30 | if rgb_img.shape[2] == 4:
31 | img = cv2.cvtColor(rgb_img, cv2.COLOR_RGBA2RGB)
32 | rows = int(rgb_img.shape[0])
33 | cols = int(rgb_img.shape[1])
34 | b, g, r = cv2.split(img)
35 | # 归一化到[0,1]
36 | b = b / 255.0
37 | g = g / 255.0
38 | r = r / 255.0
39 | hsi_img = img.copy()
40 | H, S, I = cv2.split(hsi_img)
41 | for i in range(rows):
42 | for j in range(cols):
43 | # 获得theta值
44 | num = 0.5 * ((r[i, j]-g[i, j])+(r[i, j]-b[i, j]))
45 | den = np.sqrt((r[i, j]-g[i, j])**2+(r[i, j]-b[i, j])*(g[i, j]-b[i, j]))
46 | theta = float(np.arccos(num/den))
47 | if den == 0:
48 | H = 0
49 | elif b[i, j] <= g[i, j]:
50 | H = theta
51 | else:
52 | H = 2*3.14169265 - theta
53 | min_RGB = min(min(b[i, j], g[i, j]), r[i, j])
54 | sum = b[i, j]+g[i, j]+r[i, j]
55 | if sum == 0:
56 | S = 0
57 | else:
58 | S = 1 - 3*min_RGB/sum
59 | # 归一到0-1之间
60 | H = H/(2*3.14159265)
61 | I = sum/3.0
62 | # 输出HSI图像,扩充到255以方便显示,一般H分量在[0,2pi]之间,S和I在[0,1]之间
63 | hsi_img[i, j, 0] = H*255
64 | hsi_img[i, j, 1] = S*255
65 | hsi_img[i, j, 2] = I*255
66 | hsi_img[:,:,0] = hsi_img[:,:,0]*h_value
67 | hsi_img[:,:,1] = hsi_img[:,:,0]*s_value
68 | hsi_img[:,:,1] = hsi_img[:,:,0]*i_value
69 | return hsi_img
70 |
--------------------------------------------------------------------------------
/function/ColorImageProcess/PseudoColorTrans.py:
--------------------------------------------------------------------------------
1 | import cv2
2 |
3 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
4 | from function.ColorImageProcess.HSIProcess import hsvProcess
5 |
6 |
7 | def pseudoColorTrans(img,H,S,V,type):
8 | if img.shape == 4:
9 | img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGR)
10 | img_gray = rgbToGray(img)
11 | if type == 0:
12 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_AUTUMN)
13 | elif type == 1:
14 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_BONE)
15 | elif type == 2:
16 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_JET)
17 | elif type == 3:
18 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_WINTER)
19 | elif type == 4:
20 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_RAINBOW)
21 | elif type == 5:
22 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_OCEAN)
23 | elif type == 6:
24 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_SUMMER)
25 | elif type == 7:
26 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_SPRING)
27 | elif type == 8:
28 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_COOL)
29 | elif type == 9:
30 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_HSV)
31 | elif type == 10:
32 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_PINK)
33 | elif type == 11:
34 | img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_HOT)
35 | img_color = hsvProcess(img_color,H,S,V)
36 | return img_color
37 |
38 |
39 | # img_gray = cv2.imread("../pic/beach.png",cv2.IMREAD_GRAYSCALE)
40 | # img_color = cv2.applyColorMap(img_gray,cv2.COLORMAP_JET)
41 | # img = cv2.imread('../pic/beach.png')
42 | # img_gray = pseudoColorTrans(img,type)
43 | # cv2.imshow('img_color',img_gray)
44 | # cv2.waitKey(0)
45 | # cv2.imshow('img_color',img_color)
46 | # cv2.waitKey(0)
--------------------------------------------------------------------------------
/function/ColorImageProcess/RGB2CMY.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | from function.ColorImageProcess.HSIProcess import hsvProcess
3 |
4 |
5 | def rgb2cmy(img,H,S,V):
6 | if img.shape[2] == 4:
7 | img = cv2.cvtColor(img,cv2.COLOR_RGBA2RGB)
8 | (b,g,r) = cv2.split(img)
9 | b = 1 - b/b.max()
10 | g = 1 - g/g.max()
11 | r = 1 - r/r.max()
12 | img_1 = cv2.merge([255*b,255*g,255*r])
13 | img_result = hsvProcess(img_1,H,S,V)
14 | return img_result
15 |
16 |
17 |
--------------------------------------------------------------------------------
/function/ColorImageProcess/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/ColorImageProcess/__init__.py
--------------------------------------------------------------------------------
/function/ColorImageProcess/__pycache__/HSIProcess.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/ColorImageProcess/__pycache__/HSIProcess.cpython-37.pyc
--------------------------------------------------------------------------------
/function/ColorImageProcess/__pycache__/PseudoColorTrans.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/ColorImageProcess/__pycache__/PseudoColorTrans.cpython-37.pyc
--------------------------------------------------------------------------------
/function/ColorImageProcess/__pycache__/RGB2CMY.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/ColorImageProcess/__pycache__/RGB2CMY.cpython-37.pyc
--------------------------------------------------------------------------------
/function/ColorImageProcess/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/ColorImageProcess/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/ButterWorthFilter.py:
--------------------------------------------------------------------------------
1 |
2 | import cv2
3 | import numpy as np
4 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
5 |
6 |
7 | def make_transform_matrix(image,d,s1,n):
8 | transfor_matrix = np.zeros(image.shape)
9 | center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
10 | for i in range(transfor_matrix.shape[0]):
11 | for j in range(transfor_matrix.shape[1]):
12 | def cal_distance(pa, pb):
13 | from math import sqrt
14 | dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
15 | return dis
16 |
17 | dis = cal_distance(center_point, (i, j))
18 | transfor_matrix[i, j] = 1 / ((1 + (dis / d)) ** (2 * n))
19 | return transfor_matrix
20 |
21 |
22 | def butterworthFilter(image, d, n,kind):
23 | '''
24 | 巴特沃斯低通滤波器
25 | :param image: 输入图像
26 | :param d: 滤波半径
27 | :param n: 阶数
28 | :return:
29 | '''
30 | image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
31 | image = rgbToGray(image)
32 | f = np.fft.fft2(image)
33 | fshift = np.fft.fftshift(f)
34 | s1 = np.log(np.abs(fshift))
35 | if kind == 1:
36 | d_matrix = make_transform_matrix(image,d,s1,n)
37 | elif kind == 4:
38 | d_matrix = 1-make_transform_matrix(image, d, s1, n)
39 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
40 | # 高通滤波
41 | # img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * (1-d_matrix))))
42 | img_d1 = img_d1 / img_d1.max()
43 | img_d1 = img_d1 * 255
44 | img_d1 = img_d1.astype(np.uint8)
45 | return img_d1
46 |
47 |
48 | # 定义函数,巴特沃斯带阻/通滤波模板
49 | def ButterworthBand(src, w, d0, n):
50 | template = np.zeros(src.shape, dtype=np.float32) # 构建滤波器
51 | r, c = src.shape
52 | for i in np.arange(r):
53 | for j in np.arange(c):
54 | distance = np.sqrt((i - r / 2) ** 2 + (j - c / 2) ** 2)
55 | # 巴特沃斯分布
56 | template[i, j] = 1/(1+(distance*w/(distance**2 - d0**2))**(2*n))
57 | return template
58 |
59 |
60 | def butterworthSelectFilter(image, d, n,W,kind):
61 | image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
62 | image = rgbToGray(image) # 图像灰度化
63 | f = np.fft.fft2(image) # 图像的傅里叶变换
64 | fshift = np.fft.fftshift(f) # 将低频移动到中心
65 | s1 = np.log(np.abs(fshift))
66 | if kind == 1: # 巴特沃斯带阻滤波器
67 | d_matrix = ButterworthBand(image,W,d,n)
68 | elif kind == 4: # 巴特沃斯带通滤波器
69 | d_matrix = 1-ButterworthBand(image, W, d, n)
70 | # 与模板相乘后再傅里叶逆变换
71 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
72 | img_d1 = img_d1 / img_d1.max()
73 | img_d1 = img_d1 * 255
74 | img_d1 = img_d1.astype(np.uint8)
75 | return img_d1
76 |
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/GaussianFrequencyFilter.py:
--------------------------------------------------------------------------------
1 |
2 | import cv2
3 | import numpy as np
4 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
5 |
6 | # 高斯滤波器模板
7 | def make_transform_matrix(d,image,s1):
8 | transfor_matrix = np.zeros(image.shape)
9 | center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
10 | for i in range(transfor_matrix.shape[0]):
11 | for j in range(transfor_matrix.shape[1]):
12 | def cal_distance(pa, pb):
13 | from math import sqrt
14 | dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
15 | return dis
16 |
17 | dis = cal_distance(center_point, (i, j))
18 | transfor_matrix[i, j] = np.exp(-(dis ** 2) / (2 * (d ** 2)))
19 | return transfor_matrix
20 |
21 | def GaussianFilter(image,d,kind):
22 | image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
23 | image = rgbToGray(image)
24 | f = np.fft.fft2(image)
25 | fshift = np.fft.fftshift(f)
26 | s1 = np.log(np.abs(fshift))
27 | if kind == 2:
28 | d_matrix = make_transform_matrix(d,image,s1)
29 | elif kind == 5:
30 | d_matrix = 1-make_transform_matrix(d,image,s1)
31 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
32 | img_d1 = img_d1 / img_d1.max()
33 | img_d1 = img_d1 * 255
34 | img_d1 = img_d1.astype(np.uint8)
35 | return img_d1
36 |
37 | # # 高斯选择滤波器模板
38 | # def make_select_matrix(d,image,s1,W):
39 | # transfor_matrix = np.zeros(image.shape)
40 | # center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
41 | # for i in range(transfor_matrix.shape[0]):
42 | # for j in range(transfor_matrix.shape[1]):
43 | # def cal_distance(pa,pb):
44 | # from math import sqrt
45 | # dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
46 | # return dis
47 | # dis = cal_distance(center_point,(i,j))
48 | # if dis != 0 and W != 0: # 高斯分布
49 | # transfor_matrix[i,j] =1 - np.exp(-(dis**2-d**2)/(2*(dis*W)))
50 | # return transfor_matrix
51 |
52 | # 定义函数,高斯带阻/通滤波模板
53 | def GaussianBand(src, w, d0):
54 | template = np.zeros(src.shape, dtype=np.float32) # 构建滤波器
55 | r, c = src.shape
56 | for i in np.arange(r):
57 | for j in np.arange(c):
58 | distance = np.sqrt((i - r / 2) ** 2 + (j - c / 2) ** 2)
59 | temp = ((distance**2 - d0**2)/(distance*w+0.00000001))**2
60 | template[i, j] = 1 - np.exp(-0.5 * temp)
61 | return template
62 |
63 | def GaussianSelectFilter(image,d,W,kind):
64 | image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
65 | image = rgbToGray(image)
66 | f = np.fft.fft2(image)
67 | fshift = np.fft.fftshift(f)
68 | s1 = np.log(np.abs(fshift))
69 | if kind == 2: # 高斯带阻滤波器
70 | # d_matrix = make_select_matrix(d,image,s1,W)
71 | d_matrix = GaussianBand(image,W,d)
72 | elif kind == 5: # 高斯带通滤波器
73 | # d_matrix = 1-make_select_matrix(d,image,s1,W)
74 | d_matrix = 1-GaussianBand(image,W,d)
75 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
76 | img_d1 = img_d1 / img_d1.max()
77 | img_d1 = img_d1 * 255
78 | img_d1 = img_d1.astype(np.uint8)
79 | return img_d1
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/IdealFilter.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import cv2
3 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
4 |
5 | def make_transform_matrix(d,image,s1):
6 | """
7 | 构建理想低通滤波器
8 | :param d: 滤波器半径
9 | :param image: 图像的傅里叶变换
10 | :return:
11 | """
12 | transfor_matrix = np.zeros(image.shape)
13 | center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
14 | for i in range(transfor_matrix.shape[0]):
15 | for j in range(transfor_matrix.shape[1]):
16 | def cal_distance(pa,pb):
17 | from math import sqrt
18 | dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
19 | return dis
20 | dis = cal_distance(center_point,(i,j))
21 | if dis <= d:
22 | transfor_matrix[i,j]=1
23 | else:
24 | transfor_matrix[i,j]=0
25 | return transfor_matrix
26 |
27 | def idealFilter(img,r,kind):
28 | '''
29 | 理想滤波器
30 | :param img: 输入图像
31 | :param r: 滤波器半径
32 | :param kind: 滤波器类型
33 | :return: 滤波后的图像
34 | '''
35 | img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR) # 四维转三维
36 | img = rgbToGray(img) # 灰度化
37 | f = np.fft.fft2(img) # 傅里叶变换
38 | fshift = np.fft.fftshift(f) # 将低频部分移到中心
39 | # 取绝对值:将复数变化成实数
40 | # 取对数的目的为了将数据变化到0-255
41 | s1 = np.log(np.abs(fshift))
42 | # d1 = make_transform_matrix(r, fshift, s1)
43 | if kind == 0: # 理想低通滤波
44 | d1 = make_transform_matrix(r, fshift, s1)
45 | elif kind == 3: # 理想高通滤波
46 | d1 = 1-make_transform_matrix(r, fshift, s1)
47 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d1)))
48 | img_d1 = img_d1 / img_d1.max()
49 | img_d1 = img_d1 * 255
50 | img_d1 = img_d1.astype(np.uint8)
51 | return img_d1
52 |
53 |
54 | def make_select_matrix(d,image,s1,W):
55 | """
56 | 构建理想选择滤波器
57 | :param d: 滤波器半径
58 | :param image: 图像的傅里叶变换
59 | :return:
60 | """
61 | transfor_matrix = np.zeros(image.shape)
62 | center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
63 | for i in range(transfor_matrix.shape[0]):
64 | for j in range(transfor_matrix.shape[1]):
65 | def cal_distance(pa,pb):
66 | from math import sqrt
67 | dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2) # 计算两点之间距离
68 | return dis
69 | dis = cal_distance(center_point,(i,j))
70 | # if dis <= d + W/2 and dis >= d - W/2:
71 | if dis <= d + W and dis >= d:
72 | transfor_matrix[i,j]=0
73 | else:
74 | transfor_matrix[i,j]=1
75 | return transfor_matrix
76 |
77 | def idealSelectFilter(img,r,W,kind):
78 | img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR)
79 | img = rgbToGray(img)
80 | # 傅里叶变换
81 | f = np.fft.fft2(img)
82 | # 将低频部分移到中心
83 | fshift = np.fft.fftshift(f)
84 | # 取绝对值:将复数变化成实数
85 | # 取对数的目的为了将数据变化到0-255
86 | s1 = np.log(np.abs(fshift))
87 | if kind == 0: # 理想带阻滤波器
88 | d1 = make_select_matrix(r, fshift, s1, W)
89 | elif kind == 3: # 理想带通滤波器
90 | d1 = 1-make_select_matrix(r, fshift, s1, W)
91 | # 与模板相乘后再傅里叶逆变换
92 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d1)))
93 | img_d1 = img_d1 / img_d1.max()
94 | img_d1 = img_d1 * 255
95 | img_d1 = img_d1.astype(np.uint8)
96 | return img_d1
97 |
98 | def make_NotchFilter_matrix(d,image,s1):
99 | """
100 | 构建理想陷波滤波器
101 | :param d: 滤波器半径
102 | :param image: 图像的傅里叶变换
103 | :return:
104 | """
105 | transfor_matrix = np.zeros(image.shape)
106 | # center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
107 | center_point_1 = (s1.shape[0]/4,s1.shape[1]/2)
108 | center_point_2 = (3*s1.shape[0]/4,s1.shape[1]/2)
109 | for i in range(transfor_matrix.shape[0]):
110 | for j in range(transfor_matrix.shape[1]):
111 | def cal_distance(pa,pb):
112 | from math import sqrt
113 | dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
114 | return dis
115 | dis_1 = cal_distance(center_point_1,(i,j))
116 | dis_2 = cal_distance(center_point_2,(i,j))
117 | # if dis <= d + W/2 and dis >= d - W/2:
118 | # if dis <= d + W and dis >= d:
119 | if dis_1 <= d or dis_2 <= d:
120 | transfor_matrix[i,j]=0
121 | else:
122 | transfor_matrix[i,j]=1
123 | return transfor_matrix
124 |
125 | def idealNotchFilter(img,r,kind):
126 | img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR)
127 | img = rgbToGray(img)
128 | # 傅里叶变换
129 | f = np.fft.fft2(img)
130 | # 将低频部分移到中心
131 | fshift = np.fft.fftshift(f)
132 | # fshift = fshift.astype(np.uint8)
133 | # 取绝对值:将复数变化成实数
134 | # 取对数的目的为了将数据变化到0-255
135 | s1 = np.log(np.abs(fshift))
136 | if kind == 6:
137 | d1 = make_NotchFilter_matrix(r, fshift, s1)
138 | elif kind == 7:
139 | d1 = 1-make_NotchFilter_matrix(r, fshift, s1)
140 | img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d1)))
141 | img_d1 = img_d1 / img_d1.max()
142 | img_d1 = img_d1 * 255
143 | img_d1 = img_d1.astype(np.uint8)
144 | return img_d1
145 |
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/FrequencyDomainFilter/__init__.py
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/__pycache__/ButterWorthFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/FrequencyDomainFilter/__pycache__/ButterWorthFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/__pycache__/GaussianFrequencyFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/FrequencyDomainFilter/__pycache__/GaussianFrequencyFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/__pycache__/IdealFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/FrequencyDomainFilter/__pycache__/IdealFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/FrequencyDomainFilter/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/FrequencyDomainFilter/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GeometricTrans/ImageCut.py:
--------------------------------------------------------------------------------
1 | from cv2 import selectROI
2 | from function.GeometricTrans.LargeSmall import largeSmall
3 |
4 | def cut(img,rate):
5 | '''
6 | 实现图像的剪切
7 | :param img:要剪切的图像
8 | :param rate: 图像放缩的比例
9 | :return: 返回剪切得到的图像
10 | '''
11 | # 得到手动裁剪的矩形区域
12 | bbox = selectROI(img, False)
13 | cut = img[bbox[1]:bbox[1] + bbox[3], bbox[0]:bbox[0] + bbox[2]]
14 | return largeSmall(cut, rate)
15 |
--------------------------------------------------------------------------------
/function/GeometricTrans/LargeSmall.py:
--------------------------------------------------------------------------------
1 | # import cv2
2 | from cv2 import resize
3 |
4 | def largeSmall(img,rate=100):
5 | '''
6 | 实现了图像的放缩
7 | :param img: 要放缩的图像
8 | :param rate: 图像放缩的比例
9 | :return: 返回放缩后得到的图像
10 | '''
11 | rate = rate / 100
12 | img_info = img.shape
13 | image_height = img_info[0]
14 | image_weight = img_info[1]
15 | desHeight = int(rate*image_height)
16 | desWeight = int(rate*image_weight)
17 | img = resize(img,(desWeight,desHeight))
18 | return img
19 |
--------------------------------------------------------------------------------
/function/GeometricTrans/Mirror.py:
--------------------------------------------------------------------------------
1 | from cv2 import cvtColor,COLOR_RGBA2RGB
2 | from numpy import zeros,uint8
3 | from function.GeometricTrans.LargeSmall import *
4 |
5 | def mirror(img,rate):
6 | '''
7 | 实现图像的镜像
8 | :param img: 要镜像的图像
9 | :param rate: 图像放缩的比例
10 | :return: 返回镜像后得到的图像
11 | '''
12 | imgInfo = img.shape
13 | height= imgInfo[0]
14 | width = imgInfo[1]
15 | colorChannel = imgInfo[2]
16 | # 如果图像是RGBA的,则将其转化为RGB
17 | if colorChannel == 4:
18 | img = cvtColor(img,COLOR_RGBA2RGB)
19 | colorChannel = colorChannel -1
20 | dst = zeros([height, width*2, colorChannel], uint8)
21 | # 以下循环实现了图像的镜像
22 | for i in range(height):
23 | for j in range(width):
24 | dst[i,j] = img[i,j]
25 | dst[i,width*2-j-1] = img[i,j]
26 |
27 | for i in range(height):
28 | dst[i,width] = (0, 0, 255)
29 | return largeSmall(dst, rate)
--------------------------------------------------------------------------------
/function/GeometricTrans/Ratate.py:
--------------------------------------------------------------------------------
1 | from cv2 import getRotationMatrix2D,warpAffine
2 | from math import fabs,sin,radians,cos
3 |
4 | def ratate(img,degree=0):
5 | '''
6 | 实现图像的旋转
7 | :param img: 需要旋转的图像
8 | :param degree: 旋转的角度
9 | :return: 返回旋转后的图像
10 | '''
11 | height, width = img.shape[:2]
12 | # 旋转后的尺寸
13 | heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
14 | widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
15 | # 获得仿射变换矩阵
16 | matRotation = getRotationMatrix2D((width / 2, height / 2), degree, 1)
17 | matRotation[0, 2] += (widthNew - width) / 2
18 | matRotation[1, 2] += (heightNew - height) / 2
19 | # 进行仿射变换
20 | imgRotation = warpAffine(img, matRotation, (widthNew, heightNew), borderValue=(68, 68, 68))
21 | return imgRotation
22 |
--------------------------------------------------------------------------------
/function/GeometricTrans/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GeometricTrans/__init__.py
--------------------------------------------------------------------------------
/function/GeometricTrans/__pycache__/ImageCut.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GeometricTrans/__pycache__/ImageCut.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GeometricTrans/__pycache__/LargeSmall.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GeometricTrans/__pycache__/LargeSmall.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GeometricTrans/__pycache__/Mirror.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GeometricTrans/__pycache__/Mirror.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GeometricTrans/__pycache__/Ratate.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GeometricTrans/__pycache__/Ratate.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GeometricTrans/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GeometricTrans/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GrayscaleTrans/BGR2GRAY.py:
--------------------------------------------------------------------------------
1 | from numpy import uint8
2 |
3 | def rgbToGray(img):
4 | '''
5 | 彩色图像灰度化
6 | :param img: 输入彩色图像
7 | :return: 输出灰度图像
8 | '''
9 | # 得到(r,g,b)三通道
10 | b = img[:, :, 0].copy()
11 | g = img[:, :, 1].copy()
12 | r = img[:, :, 2].copy()
13 | # 灰度化
14 | out = 0.2126 * r + 0.7152 * g + 0.0722 * b
15 | out = out.astype(uint8)
16 | return out
17 |
18 |
19 |
--------------------------------------------------------------------------------
/function/GrayscaleTrans/Binarization.py:
--------------------------------------------------------------------------------
1 | from function.GrayscaleTrans.BGR2GRAY import *
2 |
3 | def binarization(img, th=128):
4 | '''
5 | 实现了图像的二值化
6 | :param img: 输入图像
7 | :param th: 阈值
8 | :return: 返回二值图像
9 | '''
10 | _, _, colorChannel = img.shape
11 | if colorChannel != 1:
12 | img = rgbToGray(img)
13 | img[img < th] = 0
14 | img[img >= th] = 255
15 | return img
--------------------------------------------------------------------------------
/function/GrayscaleTrans/GammaTrans.py:
--------------------------------------------------------------------------------
1 | from math import pow
2 | from cv2 import normalize,NORM_MINMAX,convertScaleAbs
3 | from numpy import uint8,zeros,float32
4 | def gammaTranform(c,gamma,image):
5 | '''
6 | 图像的伽马变换(y = c*r^gamma)
7 | :param c:
8 | :param gamma:
9 | :param image:输入图像
10 | :return:
11 | '''
12 | h,w,d = image.shape[0],image.shape[1],image.shape[2]
13 | new_img = zeros((h,w,d),dtype=float32)
14 | for i in range(h):
15 | for j in range(w):
16 | new_img[i,j,0] = c*pow(image[i, j, 0], gamma)
17 | new_img[i,j,1] = c*pow(image[i, j, 1], gamma)
18 | new_img[i,j,2] = c*pow(image[i, j, 2], gamma)
19 | normalize(new_img,new_img,0,255,NORM_MINMAX)
20 | new_img = convertScaleAbs(new_img)
21 | output_imgae = new_img.astype(uint8)
22 | return output_imgae
--------------------------------------------------------------------------------
/function/GrayscaleTrans/Reverse.py:
--------------------------------------------------------------------------------
1 | # import numpy as np
2 | from numpy import copy,max,uint8
3 | def image_reverse(input_image):
4 | '''
5 | 图像反转
6 | :param input_image: 原图像
7 | :return: 反转后的图像
8 | '''
9 | input_image_cp = copy(input_image) # 输入图像的副本
10 |
11 | pixels_value_max = max(input_image_cp) # 输入图像像素的最大值
12 |
13 | output_imgae = pixels_value_max - input_image_cp # 输出图像
14 |
15 | output_imgae = output_imgae.astype(uint8)
16 |
17 | return output_imgae
--------------------------------------------------------------------------------
/function/GrayscaleTrans/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GrayscaleTrans/__init__.py
--------------------------------------------------------------------------------
/function/GrayscaleTrans/__pycache__/BGR2GRAY.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GrayscaleTrans/__pycache__/BGR2GRAY.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GrayscaleTrans/__pycache__/Binarization.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GrayscaleTrans/__pycache__/Binarization.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GrayscaleTrans/__pycache__/GammaTrans.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GrayscaleTrans/__pycache__/GammaTrans.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GrayscaleTrans/__pycache__/Reverse.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GrayscaleTrans/__pycache__/Reverse.cpython-37.pyc
--------------------------------------------------------------------------------
/function/GrayscaleTrans/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/GrayscaleTrans/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/HistogramTrans/Equalize.py:
--------------------------------------------------------------------------------
1 | # import numpy as np
2 | from numpy import where,uint8
3 | from cv2 import cvtColor,COLOR_RGBA2BGR
4 | # histogram equalization
5 | def hist_equal(img, z_max=255):
6 | if img.shape == 4:
7 | img = cvtColor(img,COLOR_RGBA2BGR)
8 | H, W, C = img.shape
9 | S = H * W * C * 1.
10 | out = img.copy()
11 | sum_h = 0.
12 | for i in range(1, 255):
13 | ind = where(img == i)
14 | sum_h += len(img[ind])
15 | z_prime = z_max / S * sum_h
16 | out[ind] = z_prime
17 | out = out.astype(uint8)
18 | return out
19 |
20 |
--------------------------------------------------------------------------------
/function/HistogramTrans/HistogramMatch.py:
--------------------------------------------------------------------------------
1 | from custom.ImageView import childwindow1
2 | from cv2 import cvtColor,COLOR_RGBA2RGB,imread
3 | from numpy import zeros_like,histogram,cumsum
4 |
5 | def HisgramMatch(img):
6 | _, _, colorChannel = img.shape
7 | if colorChannel == 4:# 4维降为3维
8 | img = cvtColor(img,COLOR_RGBA2RGB)
9 | colorChannel = colorChannel -1
10 | childwindow = childwindow1()
11 | fname = childwindow.openfile()
12 | ref = imread(fname) # 读取匹配的图像
13 | _, _, colorChannel1 = ref.shape
14 | if colorChannel1 == 4:
15 | ref = cvtColor(ref, COLOR_RGBA2RGB)
16 | out = zeros_like(img)
17 | for i in range(colorChannel):
18 | print(i)
19 | hist_img, _ = histogram(img[:, :, i], 256) # 得到图像的直方图
20 | hist_ref, _ = histogram(ref[:, :, i], 256)
21 | cdf_img = cumsum(hist_img) # 得到图像的累计直方图
22 | cdf_ref = cumsum(hist_ref)
23 |
24 | for j in range(256):
25 | tmp = abs(cdf_img[j] - cdf_ref)
26 | tmp = tmp.tolist()
27 | idx = tmp.index(min(tmp)) # 得到灰度阶差距最小的下标
28 | out[:, :, i][img[:, :, i] == j] = idx
29 |
30 | return out
31 |
--------------------------------------------------------------------------------
/function/HistogramTrans/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/HistogramTrans/__init__.py
--------------------------------------------------------------------------------
/function/HistogramTrans/__pycache__/Equalize.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/HistogramTrans/__pycache__/Equalize.cpython-37.pyc
--------------------------------------------------------------------------------
/function/HistogramTrans/__pycache__/HistogramMatch.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/HistogramTrans/__pycache__/HistogramMatch.cpython-37.pyc
--------------------------------------------------------------------------------
/function/HistogramTrans/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/HistogramTrans/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/IdCardPicGenerate/IdCardPicGenerate.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | import dlib
4 | from matplotlib import pyplot as plt
5 |
6 |
7 | def idCardPicGenerate(img, type):
8 | detector = dlib.get_frontal_face_detector() # 返回人脸的矩形框
9 | # 返回人脸重要的68个点的位置
10 | landmark_predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
11 | if img.shape[2] == 4:
12 | img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGR)
13 | imgg = img.copy()
14 | t = img.shape
15 | faces = detector(img, 1)
16 | print(faces)
17 | mask = np.zeros(img.shape[:2], np.uint8)
18 | bgdModel = np.zeros((1, 65), np.float64)
19 | fgdModel = np.zeros((1, 65), np.float64)
20 | if (len(faces) > 0):
21 | for k, d in enumerate(faces):
22 | left = max(int((3 * d.left() - d.right()) / 2), 1)
23 | top = max(int((3 * d.top() - d.bottom()) / 2) - 50, 1)
24 | right = min(int((3 * d.right() - d.left()) / 2), t[1])
25 | bottom = min(int((3 * d.bottom() - d.top()) / 2), t[0])
26 | rect = (left, top, right, bottom)
27 | rect_reg = (d.left(), d.top(), d.right(), d.bottom())
28 | # shape = landmark_predictor(img, d)
29 | shape = landmark_predictor(img, d)
30 | print(shape)
31 | else:
32 | exit(0)
33 | # mask会保存明显的背景像素为0,明显的前景像素为1,可能的背景像素为2,可能的前景像素为3
34 | cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 100,
35 | cv2.GC_INIT_WITH_RECT) # 函数返回值为mask,bgdModel,fgdModel
36 | # 利用mask做模板
37 | mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8') # 0和2做背景
38 |
39 | # 背景颜色
40 | bg_color = [(225, 166, 23), (0, 0, 255), (255, 255, 255)]
41 | img = img * mask2[:, :, np.newaxis] # 使用蒙板来获取前景区域
42 | erode = cv2.erode(img, None, iterations=1) # 腐蚀操作
43 | dilate = cv2.dilate(erode, None, iterations=1) # 膨胀操作
44 | for i in range(t[0]): # 高、
45 | for j in range(t[1]):
46 | if max(dilate[i, j]) <= 0:
47 | dilate[i, j] = bg_color[type]
48 | img = img[rect[1]:rect[3], rect[0]:rect[2]]
49 | dilate = dilate[rect[1]:rect[3], rect[0]:rect[2]]
50 | output_im = cv2.resize(dilate, (361, 381))
51 | return output_im
--------------------------------------------------------------------------------
/function/IdCardPicGenerate/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/IdCardPicGenerate/__init__.py
--------------------------------------------------------------------------------
/function/IdCardPicGenerate/__pycache__/IdCardPicGenerate.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/IdCardPicGenerate/__pycache__/IdCardPicGenerate.cpython-37.pyc
--------------------------------------------------------------------------------
/function/IdCardPicGenerate/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/IdCardPicGenerate/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SharpenTrans/Laplacian.py:
--------------------------------------------------------------------------------
1 | # import cv2
2 | # import numpy as np
3 |
4 |
5 | # laplacian filter
6 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
7 | from numpy import zeros,sum,clip,float,uint8
8 |
9 | def laplacian_filter(img, K_size=3):
10 | H, W, C = img.shape
11 | gray = rgbToGray(img)
12 | # zero padding
13 | pad = K_size // 2
14 | out = zeros((H + pad * 2, W + pad * 2), dtype=float)
15 | out[pad: pad + H, pad: pad + W] = gray.copy().astype(float)
16 | tmp = out.copy()
17 | # laplacian kernle
18 | K = [[0., 1., 0.],[1., -4., 1.], [0., 1., 0.]]
19 | # filtering
20 | for y in range(H):
21 | for x in range(W):
22 | out[pad + y, pad + x] = sum(K * (tmp[y: y + K_size, x: x + K_size]))
23 | out = clip(out, 0, 255)
24 | out = out[pad: pad + H, pad: pad + W].astype(uint8)
25 | return out
--------------------------------------------------------------------------------
/function/SharpenTrans/Prewitt.py:
--------------------------------------------------------------------------------
1 | # import cv2
2 | # import numpy as np
3 | from cv2 import addWeighted
4 | from numpy import zeros,expand_dims,float,uint8,sum,clip
5 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
6 |
7 | # prewitt filter
8 | def prewitt_filter(img, K_size=3):
9 | gray = rgbToGray(img)
10 | if len(img.shape) == 3:
11 | H, W, C = img.shape
12 | else:
13 | img = expand_dims(img, axis=-1)
14 | H, W, C = img.shape
15 | # 填充0
16 | pad = K_size // 2
17 | out = zeros((H + pad * 2, W + pad * 2), dtype=float)
18 | out[pad: pad + H, pad: pad + W] = gray.copy().astype(float)
19 | tmp = out.copy()
20 | out_v = out.copy()
21 | out_h = out.copy()
22 | ## prewitt 水平方向的核
23 | Kv = [[-1., -1., -1.],[0., 0., 0.], [1., 1., 1.]]
24 | ## prewitt 竖直方向的核
25 | Kh = [[-1., 0., 1.],[-1., 0., 1.],[-1., 0., 1.]]
26 | # filtering
27 | for y in range(H):
28 | for x in range(W):
29 | out_v[pad + y, pad + x] = sum(Kv * (tmp[y: y + K_size, x: x + K_size]))
30 | out_h[pad + y, pad + x] = sum(Kh * (tmp[y: y + K_size, x: x + K_size]))
31 | out_v = clip(out_v, 0, 255)
32 | out_h = clip(out_h, 0, 255)
33 | out_v = out_v[pad: pad + H, pad: pad + W].astype(uint8)
34 | out_h = out_h[pad: pad + H, pad: pad + W].astype(uint8)
35 | dst = addWeighted(out_v, 0.5, out_h, 0.5, 0)
36 | return dst
37 |
38 | # 读取图像
39 | # img = cv2.imread('../pic/boy.png')
40 | # prewitt_filter(img)
--------------------------------------------------------------------------------
/function/SharpenTrans/Robert.py:
--------------------------------------------------------------------------------
1 | # import cv2
2 | # import numpy as np
3 | # import matplotlib.pyplot as plt
4 | from cv2 import convertScaleAbs,addWeighted,cvtColor,COLOR_BGR2GRAY,CV_16S,filter2D
5 | from function.GrayscaleTrans.BGR2GRAY import rgbToGray
6 |
7 |
8 | def robert(img):
9 | img1 = rgbToGray(img)
10 | img2 = rgbToGray(img)
11 | # img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
12 | r, c = img1.shape
13 | # r_sunnzi = [[-1, -1], [1, 1]]
14 | r_sunnzi_x = [[-1, 0], [0, 1]]
15 | r_sunnzi_y = [[0, -1], [1, 0]]
16 | for x in range(r):
17 | for y in range(c):
18 | if (y + 2 <= c) and (x + 2 <= r):
19 | imgChild = img1[x:x + 2, y:y + 2]
20 | list_robert = r_sunnzi_x * imgChild
21 | img1[x, y] = abs(list_robert.sum()) # 求和加绝对值
22 | for x in range(r):
23 | for y in range(c):
24 | if (y + 2 <= c) and (x + 2 <= r):
25 | imgChild = img2[x:x + 2, y:y + 2]
26 | list_robert = r_sunnzi_y * imgChild
27 | img2[x, y] = abs(list_robert.sum()) # 求和加绝对值
28 | # 转uint8
29 | absX = convertScaleAbs(img1)
30 | absY = convertScaleAbs(img2)
31 | result = addWeighted(absX, 0.5, absY, 0.5, 0)
32 | # result = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)
33 | # cv2.imshow("result",result)
34 | # cv2.waitKey(0)
35 | return result
36 |
37 |
38 | def cv2_robert(img):
39 | # lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
40 |
41 | # 灰度化处理图像
42 | grayImage = cvtColor(img, COLOR_BGR2GRAY)
43 |
44 | # Roberts算子
45 | kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
46 | kernely = np.array([[0, -1], [1, 0]], dtype=int)
47 | x = filter2D(grayImage, CV_16S, kernelx)
48 | y = filter2D(grayImage, CV_16S, kernely)
49 | # 转uint8
50 | absX = convertScaleAbs(x)
51 | absY = convertScaleAbs(y)
52 | result = addWeighted(absX, 0.5, absY, 0.5, 0)
53 | return result
54 | #
55 | # # 显示图形
56 | # titles = [u'原始图像', u'Roberts算子']
57 | # images = [lenna_img, Roberts]
58 | # for i in range(2):
59 | # plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
60 | # plt.title(titles[i])
61 | # plt.xticks([]), plt.yticks([])
62 | # plt.show()
63 |
64 | # 读取图像
65 | # img = cv2.imread('../pic/boy.png')
66 | # robert(img)
67 | # cv2_robert(img)
68 |
--------------------------------------------------------------------------------
/function/SharpenTrans/SobelFilter.py:
--------------------------------------------------------------------------------
1 | # import cv2
2 | # import numpy as np
3 | from cv2 import CV_16S,Sobel,convertScaleAbs,addWeighted
4 | from numpy import expand_dims,zeros,float,sum, clip
5 | from function.GrayscaleTrans.BGR2GRAY import *
6 |
7 | # sobel filter
8 | def sobel_filter(img, K_size=3):
9 | if len(img.shape) == 3:
10 | H, W, C = img.shape
11 | else:
12 | img = expand_dims(img, axis=-1)
13 | H, W, C = img.shape
14 | # 填充0
15 | gray = rgbToGray(img) # 灰度化
16 | pad = K_size // 2
17 | out = zeros((H + pad * 2, W + pad * 2), dtype=float)
18 | out[pad: pad + H, pad: pad + W] = gray.copy().astype(float)
19 | tmp = out.copy()
20 | out_v = out.copy()
21 | out_h = out.copy()
22 | ## 水平x方向
23 | Kx = [[1., 0., -1.], [2., 0., -2.], [1., 0., -1.]]
24 | ## 竖直y方向
25 | Ky = [[1., 2., 1.],[0., 0., 0.], [-1., -2., -1.]]
26 | for y in range(H):
27 | for x in range(W):
28 | out_v[pad + y, pad + x] = sum(Ky * (tmp[y: y + K_size, x: x + K_size]))
29 | out_h[pad + y, pad + x] = sum(Kx * (tmp[y: y + K_size, x: x + K_size]))
30 | out_v = clip(out_v, 0, 255)
31 | out_h = clip(out_h, 0, 255)
32 | out_v = out_v[pad: pad + H, pad: pad + W].astype(uint8)
33 | out_h = out_h[pad: pad + H, pad: pad + W].astype(uint8)
34 | dst = addWeighted(out_v, 0.5, out_h, 0.5, 0) # 合并两个方向得到的结果
35 | return dst
36 |
37 | def cv2_sobel(img):
38 |
39 | x = Sobel(img, CV_16S, 1, 0)
40 | y = Sobel(img, CV_16S, 0, 1)
41 |
42 | absX = convertScaleAbs(x) # 转回unit8
43 | absY = convertScaleAbs(y)
44 |
45 | dst = addWeighted(absX, 0.5, absY, 0.5, 0)
46 |
--------------------------------------------------------------------------------
/function/SharpenTrans/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SharpenTrans/__init__.py
--------------------------------------------------------------------------------
/function/SharpenTrans/__pycache__/Laplacian.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SharpenTrans/__pycache__/Laplacian.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SharpenTrans/__pycache__/Prewitt.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SharpenTrans/__pycache__/Prewitt.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SharpenTrans/__pycache__/Robert.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SharpenTrans/__pycache__/Robert.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SharpenTrans/__pycache__/SobelFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SharpenTrans/__pycache__/SobelFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SharpenTrans/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SharpenTrans/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SmoothingTrans/GaussianFilter.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import math
3 | import cv2
4 | # 计算高斯卷积核
5 | def gausskernel(size,sigma=1.0):
6 | gausskernel=np.zeros((size,size),np.float32)
7 | for i in range (size):
8 | for j in range (size):
9 | norm=math.pow(i-1,2)+pow(j-1,2)
10 | gausskernel[i,j]=math.exp(-norm/(2*math.pow(sigma,2))) # 求高斯卷积
11 | sum=np.sum(gausskernel) # 求和
12 | kernel=gausskernel/sum # 归一化
13 | return kernel
14 |
15 | # 高斯滤波
16 | def gaussian_filter(img,size=3,sigma=1.3):
17 | if img.shape[2] == 4:
18 | img = cv2.cvtColor(img,cv2.COLOR_RGBA2GRAY)
19 | h=img.shape[0]
20 | w=img.shape[1]
21 | img1=np.zeros((h,w),np.uint8)
22 | kernel=gausskernel(size,sigma) # 计算高斯卷积核
23 | for i in range (1,h-1):
24 | for j in range (1,w-1):
25 | sum=0
26 | for k in range(-1,2):
27 | for l in range(-1,2):
28 | sum+=img[i+k,j+l]*kernel[k+1,l+1] # 高斯滤波
29 | img1[i,j]=sum
30 | return img1
--------------------------------------------------------------------------------
/function/SmoothingTrans/MeanFilter.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | # import numpy as np
3 | from numpy import zeros,mean,uint8,float
4 |
5 | def mean_filter(img, K_size=3):
6 | if img.shape[2] == 4:
7 | img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGR)
8 | H, W, C = img.shape
9 | # 填充0
10 | pad = K_size // 2
11 | out = zeros((H + pad * 2, W + pad * 2, C), dtype=float)
12 | out[pad: pad + H, pad: pad + W] = img.copy().astype(float)
13 | tmp = out.copy()
14 |
15 | # 算术均值滤波
16 | for y in range(H):
17 | for x in range(W):
18 | for c in range(C):
19 | out[pad + y, pad + x, c] = mean(tmp[y: y + K_size, x: x + K_size, c])
20 |
21 | out = out[pad: pad + H, pad: pad + W].astype(uint8)
22 |
23 | return out
--------------------------------------------------------------------------------
/function/SmoothingTrans/MedianFilter.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | from numpy import zeros,median,uint8,float
3 |
4 | def median_filter(img, K_size=3):
5 | H, W, C = img.shape
6 | if img.shape[2] == 4:
7 | img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGR)
8 | # 填充0
9 | pad = K_size // 2
10 | out = zeros((H + pad*2, W + pad*2, C), dtype=float)
11 | out[pad:pad+H, pad:pad+W] = img.copy().astype(float)
12 |
13 | tmp = out.copy()
14 |
15 | # filtering
16 | for y in range(H):
17 | for x in range(W):
18 | for c in range(C):
19 | out[pad+y, pad+x, c] = median(tmp[y:y+K_size, x:x+K_size, c])
20 |
21 | out = out[pad:pad+H, pad:pad+W].astype(uint8)
22 |
23 | return out
--------------------------------------------------------------------------------
/function/SmoothingTrans/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SmoothingTrans/__init__.py
--------------------------------------------------------------------------------
/function/SmoothingTrans/__pycache__/GaussianFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SmoothingTrans/__pycache__/GaussianFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SmoothingTrans/__pycache__/MeanFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SmoothingTrans/__pycache__/MeanFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SmoothingTrans/__pycache__/MedianFilter.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SmoothingTrans/__pycache__/MedianFilter.cpython-37.pyc
--------------------------------------------------------------------------------
/function/SmoothingTrans/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/SmoothingTrans/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/function/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/__init__.py
--------------------------------------------------------------------------------
/function/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/function/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/histogram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/histogram.png
--------------------------------------------------------------------------------
/icons/branch-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/branch-close.png
--------------------------------------------------------------------------------
/icons/branch-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/branch-open.png
--------------------------------------------------------------------------------
/icons/color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/color.png
--------------------------------------------------------------------------------
/icons/main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/main.png
--------------------------------------------------------------------------------
/icons/右旋转.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/右旋转.png
--------------------------------------------------------------------------------
/icons/左旋转.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/左旋转.png
--------------------------------------------------------------------------------
/icons/直方图.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/icons/直方图.png
--------------------------------------------------------------------------------
/images/Aerial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/Aerial.png
--------------------------------------------------------------------------------
/images/beach.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/beach.png
--------------------------------------------------------------------------------
/images/board_salt.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/board_salt.tif
--------------------------------------------------------------------------------
/images/boy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/boy.png
--------------------------------------------------------------------------------
/images/boy_salt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/boy_salt.png
--------------------------------------------------------------------------------
/images/breast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/breast.png
--------------------------------------------------------------------------------
/images/caricature.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/caricature.png
--------------------------------------------------------------------------------
/images/espace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/espace.png
--------------------------------------------------------------------------------
/images/lena (2).bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/lena (2).bmp
--------------------------------------------------------------------------------
/images/lena.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/lena.bmp
--------------------------------------------------------------------------------
/images/watch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/watch.jpg
--------------------------------------------------------------------------------
/images/界面.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flykite6/Digital_Image_Process/a3177e42a7ff72df81eb7f3a0f3c35c1a954515f/images/界面.png
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from cv2 import cvtColor,calcHist,imread,COLOR_GRAY2BGR
3 | import matplotlib.pyplot as plt
4 | from PyQt5.QtCore import Qt
5 | from PyQt5.QtGui import QIcon
6 | from PyQt5.QtWidgets import QAction, QMainWindow, QApplication, QDockWidget, QLabel
7 |
8 | from custom.stackedWidget import StackedWidget
9 | from custom.treeView import FileSystemTreeView
10 | from custom.listWidgets import FuncListWidget, UsedListWidget
11 | from custom.graphicsView import GraphicsView
12 | from function.GeometricTrans.Ratate import ratate
13 |
14 |
15 | class MyApp(QMainWindow):
16 | def __init__(self):
17 | super(MyApp, self).__init__()
18 | QApplication.processEvents()
19 | self.childArea = childWindow()
20 | self.tool_bar = self.addToolBar('工具栏')
21 | self.action_right_rotate = QAction(QIcon("icons/右旋转.png"), "向右旋转90", self)
22 | self.action_left_rotate = QAction(QIcon("icons/左旋转.png"), "向左旋转90°", self)
23 | self.action_histogram = QAction(QIcon("icons/直方图.png"), "直方图", self)
24 | self.action_right_rotate.triggered.connect(self.right_rotate)
25 | self.action_left_rotate.triggered.connect(self.left_rotate)
26 | self.action_histogram.triggered.connect(self.histogram)
27 | # 将上述动作关联到某一个菜单项里面
28 | self.tool_bar.addActions((self.action_left_rotate, self.action_right_rotate, self.action_histogram))
29 |
30 | self.useListWidget = UsedListWidget(self)
31 | self.funcListWidget = FuncListWidget(self)
32 | self.stackedWidget = StackedWidget(self)
33 | self.fileSystemTreeView = FileSystemTreeView(self)
34 | self.graphicsView = GraphicsView(self)
35 |
36 | self.dock_file = QDockWidget(self)
37 | self.dock_file.setWidget(self.fileSystemTreeView)
38 | self.dock_file.setTitleBarWidget(QLabel('目录'))
39 | self.dock_file.setFeatures(QDockWidget.NoDockWidgetFeatures)
40 |
41 | self.dock_func = QDockWidget(self)
42 | self.dock_func.setWidget(self.funcListWidget)
43 | self.dock_func.setTitleBarWidget(QLabel('图像操作'))
44 | self.dock_func.setFeatures(QDockWidget.NoDockWidgetFeatures)
45 |
46 | self.dock_used = QDockWidget(self)
47 | self.dock_used.setWidget(self.useListWidget)
48 | self.dock_used.setTitleBarWidget(QLabel('已选操作'))
49 | self.dock_used.setFeatures(QDockWidget.NoDockWidgetFeatures)
50 | self.dock_used.setFeatures(QDockWidget.NoDockWidgetFeatures)
51 |
52 | self.dock_attr = QDockWidget(self)
53 | self.dock_attr.setWidget(self.stackedWidget)
54 | self.dock_attr.setTitleBarWidget(QLabel('属性'))
55 | self.dock_attr.setFeatures(QDockWidget.NoDockWidgetFeatures)
56 | self.dock_attr.close()
57 |
58 | self.setCentralWidget(self.graphicsView)
59 | self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_file)
60 | self.dock_file.setMinimumWidth(400)
61 | self.dock_file.showMinimized()
62 | self.addDockWidget(Qt.TopDockWidgetArea, self.dock_func)
63 | self.addDockWidget(Qt.RightDockWidgetArea, self.dock_used)
64 | self.dock_used.setMinimumWidth(400)
65 | self.dock_used.showMinimized()
66 | self.addDockWidget(Qt.RightDockWidgetArea, self.dock_attr)
67 | self.dock_attr.setMinimumHeight(500)
68 |
69 | self.setWindowTitle('数字图像处理')
70 | self.setWindowIcon(QIcon('icons/main.png'))
71 | self.src_img = None
72 | self.cur_img = None
73 |
74 | def update_image(self):
75 | if self.src_img is None:
76 | return
77 | img = self.process_image()
78 | self.cur_img = img
79 | self.graphicsView.update_image(img)
80 |
81 | def change_image(self, img):
82 | self.src_img = img
83 | img = self.process_image()
84 | self.cur_img = img
85 | self.graphicsView.change_image(img)
86 |
87 | def process_image(self):
88 | img = self.src_img.copy()
89 | for i in range(self.useListWidget.count()):
90 | img = self.useListWidget.item(i)(img)
91 | return img
92 |
93 | def right_rotate(self):
94 | self.cur_img = ratate(self.cur_img,90)
95 | self.graphicsView.rotate(90)
96 |
97 | def left_rotate(self):
98 | self.cur_img = ratate(self.cur_img, -90)
99 | self.graphicsView.rotate(-90)
100 |
101 | def histogram(self):
102 | color = ('b', 'g', 'r')
103 | img = self.cur_img
104 | shape = img.shape
105 | if len(shape) != 3:
106 | img = cvtColor(self.cur_img,COLOR_GRAY2BGR)
107 | for i, col in enumerate(color):
108 | histr = calcHist([img], [i], None, [256], [0, 256])
109 | histr = histr.flatten()
110 | plt.plot(range(256), histr, color=col)
111 | plt.xlim([0, 256])
112 | plt.savefig('histogram.png')
113 | plt.close()
114 | self.img = imread('./histogram.png')
115 | self.childArea.display(self.img)
116 | self.childArea.show()
117 |
118 |
119 | class childWindow(QMainWindow):
120 | def __init__(self,parent=None):
121 | super(childWindow, self).__init__(parent)
122 | self.setWindowTitle('图像的直方图')
123 | self.graphicsView1 = GraphicsView(self)
124 | self.setCentralWidget(self.graphicsView1)
125 | def display(self,img):
126 | self.graphicsView1.change_image(img)
127 |
128 |
129 |
130 |
131 |
132 |
133 | if __name__ == "__main__":
134 | app = QApplication(sys.argv)
135 | app.setStyleSheet(open('styleSheet.qss', encoding='utf-8').read())
136 | window = MyApp()
137 | window.show()
138 | sys.exit(app.exec_())
139 |
--------------------------------------------------------------------------------
/styleSheet.qss:
--------------------------------------------------------------------------------
1 | *{
2 | font-family: 微软雅黑;
3 | color: #BBBBBB;
4 | background-color: #2F2F2F;
5 | }
6 |
7 | /* 设置目录树样式 */
8 | QTreeView{
9 | show-decoration-selected: 1;
10 | }
11 | QTreeView::item{
12 | height: 30px;
13 | }
14 | QTreeView::item:hover, QTreeView::branch:hover{
15 | background: #4B6EAF;
16 | }
17 | QTreeView::item:selected, QTreeView::branch:selected{
18 | background: #4B6EAF;
19 | }
20 | QTreeView::branch{
21 | color: #BBBBBB;
22 | }
23 | QTreeView::branch:has-children:!has-siblings:closed,
24 | QTreeView::branch:closed:has-children:has-siblings {
25 | border-image: none;
26 | image: url(icons/branch-close.png);
27 | }
28 | QTreeView::branch:open:has-children:!has-siblings,
29 | QTreeView::branch:open:has-children:has-siblings {
30 | border-image: none;
31 | image: url(icons/branch-open.png);
32 | }
33 |
34 | /* 设置标签样式 */
35 | QLabel{
36 | font-size: 18px;
37 | border: 1px solid #BBBBBB;
38 | border-width: 1px 1px 0px 1px;
39 | }
40 |
41 | /* 设置视图样式 */
42 | QGraphicsView{
43 | border: 1px solid #BBBBBB;
44 | background-color: #444444;
45 | }
46 |
47 | /* 设置列表样式 */
48 | QListWidget::Item{
49 | border: 1px solid #BBBBBB;
50 | font-size: 20px;
51 | background: #717678;
52 | color: #DDDDDD;
53 | }
54 |
55 | QListWidget::Item:hover{
56 | background: #4B6EAF;
57 | }
58 |
59 | FuncListWidget::Item{
60 | border-style: inset;
61 | border-radius: 8px;
62 | border: 1px solid #999999;
63 | margin:0px 1px 0px 0px
64 | }
65 |
66 | UsedListWidget::Item{
67 | border: 2px solid #999999;
68 | margin:0px 0px 1px 0px
69 | }
70 |
71 | UsedListWidget::Item:selected{
72 | background: #99CCFF;
73 | }
74 |
75 |
76 | /* 设置表格样式 */
77 | QTableWidget{
78 | alternate-background-color: #444444;
79 | }
80 |
81 |
82 | QToolButton:hover{
83 | background: #4B6EAF;
84 | }
85 |
86 |
87 |
--------------------------------------------------------------------------------