├── .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 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 | 11 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 数字图像处理系统 2 | 3 | #### 软件界面 4 | 5 | ![interface Image](https://github.com/flykite6/Digital_Image_Process/raw/master/images/界面.png) 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 | --------------------------------------------------------------------------------