├── images └── main.png ├── Image_Processing ├── Image_Processing.fig └── Image_Processing.m ├── LICENSE └── README.md /images/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlyMarco/MATLAB_Image_Processing/HEAD/images/main.png -------------------------------------------------------------------------------- /Image_Processing/Image_Processing.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlyMarco/MATLAB_Image_Processing/HEAD/Image_Processing/Image_Processing.fig -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Temmie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MATLAB Image Processing Toolkit 2 | 3 | ![Screenshot](./images/main.png) 4 | 5 | [![MATLAB](https://img.shields.io/badge/MATLAB-R2018b+-blue.svg)](https://www.mathworks.com/products/matlab.html) 6 | [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) 7 | 8 | ## 📋 项目简介 | Overview 9 | 10 | 基于 MATLAB GUIDE 开发的综合性图像处理工具箱,集成了经典图像处理算法与实时可视化分析功能。本项目采用模块化设计,实现了从基础几何变换到高级图像分析的完整工作流,适用于数字图像处理教学、算法验证和快速原型开发。 11 | 12 | A comprehensive image processing toolkit developed with MATLAB GUIDE, integrating classical algorithms with real-time visualization capabilities. Features modular architecture and complete workflow from basic geometric transformations to advanced image analysis. 13 | 14 | ## 🎥 演示视频 | Demo Videos 15 | 16 | - 🇨🇳 [Bilibili 演示](https://www.bilibili.com/video/BV1yX4y1n7Bz) 17 | - 🌍 [YouTube Demo](https://www.youtube.com/watch?v=YJiI0nK1f4g) 18 | 19 | ## ✨ 核心特性 | Key Features 20 | 21 | ### 🎯 实时可视化系统 22 | - **双视图对比显示**: 原始图像与处理结果并排显示 23 | - **像素波形分析**: 实时显示图像首行像素的 RGB/灰度分量波形 24 | - **直方图统计**: 动态更新图像灰度/颜色分布直方图 25 | - **智能类型检测**: 自动识别彩色/灰度图像并切换对应的可视化模式 26 | 27 | ### 🔧 技术实现亮点 28 | - 基于 MATLAB GUIDE 的图形用户界面 29 | - 事件驱动的回调函数架构 30 | - handles 结构体实现状态管理 31 | - 模块化函数设计 (`gUpdate22`/`gUpdate23`) 32 | - 支持格式: JPG, PNG, BMP, JPEG 33 | 34 | ## 🚀 功能模块 | Functional Modules 35 | 36 | ### 1️⃣ 几何变换 | Geometric Transformations 37 | 38 | | 功能 | 实现方法 | 参数控制 | 39 | |------|---------|---------| 40 | | **水平/垂直镜像** | `fliplr()` / `flipud()` | 按钮触发 | 41 | | **图像平移** | `imtranslate()` 累积偏移量 | 双滑块实时控制 | 42 | | **图像旋转** | `imrotate()` 双线性插值 | 滑块 0-360° | 43 | | **图像缩放** | `imresize()` 最近邻插值 + `imcrop()` | 滑块比例控制 | 44 | 45 | **技术细节**: 46 | - 平移功能通过增量向量 `V = [Δh, Δv]` 实现累积变换 47 | - 旋转和缩放基于原始图像,避免累积误差 48 | - 缩放后自动裁剪至原始尺寸,保持显示一致性 49 | 50 | ### 2️⃣ 图像滤波 | Image Filtering 51 | 52 | #### 空间域滤波器 53 | 54 | ```matlab 55 | % 均值滤波 - 3×3 平均模板 56 | h = fspecial('average'); 57 | 58 | % 高斯滤波 - 8×8 窗口, σ=1.7 59 | h = fspecial('gaussian', [8 8], 1.7); 60 | 61 | % 中值滤波 - 分通道处理 RGB 62 | r = medfilt2(img(:,:,1)); 63 | g = medfilt2(img(:,:,2)); 64 | b = medfilt2(img(:,:,3)); 65 | ``` 66 | 67 | **应用场景**: 68 | - **均值滤波**: 快速去噪,适合高斯噪声 69 | - **中值滤波**: 保边去噪,适合椒盐噪声 70 | - **高斯滤波**: 平滑图像,保留更多细节 71 | 72 | ### 3️⃣ 边缘检测 | Edge Detection 73 | 74 | 实现了五种经典边缘检测算子: 75 | 76 | | 算子 | 原理 | 特点 | 77 | |------|------|------| 78 | | **Sobel** | 3×3 梯度算子 | 抗噪性好,适合实时处理 | 79 | | **Roberts** | 2×2 交叉差分 | 计算简单,定位精确 | 80 | | **Prewitt** | 3×3 平滑梯度 | 平滑效果好 | 81 | | **LoG** | 拉普拉斯高斯 | 二阶导数,对噪声敏感 | 82 | | **Canny** | 多阶段优化算法 | 精度最高,业界标准 | 83 | 84 | **实现细节**: 85 | - 自动将彩色图像转换为灰度图 (`rgb2gray`) 86 | - 使用 MATLAB 内置优化的 `edge()` 函数 87 | - 边缘检测结果为二值图像 88 | 89 | ### 4️⃣ 图像增强 | Image Enhancement 90 | 91 | #### 对比度增强 92 | ```matlab 93 | % 亮增强 - 扩展暗部细节 94 | imadjust(img, [0, 0.9], [0, 1]); 95 | 96 | % 暗增强 - 扩展亮部细节 97 | imadjust(img, [0.1, 1], [0, 1]); 98 | ``` 99 | 100 | #### 直方图均衡化 101 | - 基于 `histeq()` 实现全局对比度自适应增强 102 | - 自动重新分配灰度级,提高图像可视性 103 | - 适用于低对比度、曝光不足的图像 104 | 105 | ### 5️⃣ 图像运算 | Image Operations 106 | 107 | #### 图像叠加 (Weighted Addition) 108 | ```matlab 109 | alpha = 0.5; 110 | result = imadd(alpha * img1, alpha * img2); 111 | ``` 112 | - 加权系数 α = 0.5,实现等权混合 113 | - 自动尺寸匹配 (`imresize`) 114 | 115 | #### 图像融合 (Blend Fusion) 116 | ```matlab 117 | result = imfuse(img1, img2, 'blend'); 118 | ``` 119 | - 使用 MATLAB 的 `imfuse` 高级融合算法 120 | - 支持多种融合模式 121 | 122 | ### 6️⃣ 图像分割 | Image Segmentation 123 | 124 | **阈值分割** - 基于全局阈值的二值化 125 | ```matlab 126 | binary = rgb2gray(img) > threshold; 127 | ``` 128 | - 滑块实时调整阈值 (0-255) 129 | - 自动转换为灰度图后分割 130 | - 适用于背景简单、对比度高的场景 131 | 132 | ## 🏗️ 系统架构 | System Architecture 133 | 134 | ### GUI 组件布局 135 | 136 | ``` 137 | ┌─────────────────────────────────────────────────┐ 138 | │ [Open] [Save] [Reset] [Exit] │ 139 | ├──────────────┬──────────────────────────────────┤ 140 | │ │ Control Panel │ 141 | │ Original │ ├─ Geometric Transform │ 142 | │ Image │ ├─ Filtering │ 143 | │ (g11) │ ├─ Edge Detection │ 144 | │ │ ├─ Enhancement │ 145 | ├──────────────┤ └─ Segmentation │ 146 | │ Processed │ │ 147 | │ Image │ Sliders: │ 148 | │ (g12) │ - H/V Translation │ 149 | │ │ - Rotation (0-360°) │ 150 | ├──────────────┤ - Resize (0.1-2.0×) │ 151 | │ Waveform │ - Threshold (0-255) │ 152 | │ (g21, g22) │ │ 153 | ├──────────────┤ │ 154 | │ Histogram │ │ 155 | │ (g23) │ │ 156 | └──────────────┴──────────────────────────────────┘ 157 | ``` 158 | 159 | ### 状态管理机制 160 | 161 | ```matlab 162 | handles.img % 当前处理后的图像 163 | handles.i % 原始图像备份 164 | handles.h % 水平平移累积量 165 | handles.v % 垂直平移累积量 166 | handles.file % 文件路径 167 | ``` 168 | 169 | ### 可视化更新流程 170 | 171 | ``` 172 | 用户操作 → 回调函数 → 图像处理 → 更新显示 173 | ├─ 更新 g12 (处理图) 174 | ├─ 检测图像类型 175 | ├─ 调用 gUpdate22/23 176 | │ ├─ 更新波形图 (g22) 177 | │ └─ 更新直方图 (g23) 178 | └─ 保存状态 (guidata) 179 | ``` 180 | 181 | ## 🔬 算法性能 | Algorithm Performance 182 | 183 | | 操作类型 | 时间复杂度 | 空间复杂度 | 备注 | 184 | |---------|-----------|-----------|------| 185 | | 几何变换 | O(n) | O(n) | n = 像素总数 | 186 | | 均值/高斯滤波 | O(n·k²) | O(k²) | k = 卷积核大小 | 187 | | 中值滤波 | O(n·k²·log k) | O(k²) | 排序开销 | 188 | | 边缘检测 | O(n) | O(n) | 优化实现 | 189 | | 直方图均衡化 | O(n + L) | O(L) | L = 灰度级数 | 190 | | 阈值分割 | O(n) | O(n) | 最快速的分割 | 191 | 192 | ## 📦 系统要求 | Requirements 193 | 194 | ### 必需环境 195 | - **MATLAB**: R2018b 或更高版本 196 | - **工具箱**: Image Processing Toolbox 197 | - **操作系统**: Windows / macOS / Linux 198 | 199 | ### 推荐配置 200 | - **内存**: ≥ 4GB RAM 201 | - **处理器**: Intel i5 或同等性能 202 | - **显示器**: 1920×1080 或更高分辨率 203 | 204 | ## 🚀 快速开始 | Quick Start 205 | 206 | ### 安装步骤 207 | 208 | 1. **克隆仓库** 209 | ```bash 210 | git clone https://github.com/OlyMarco/MATLAB_Image_Processing.git 211 | cd MATLAB_Image_Processing 212 | ``` 213 | 214 | 2. **启动 MATLAB** 215 | - 打开 MATLAB 216 | - 导航到项目目录 217 | 218 | 3. **运行程序** 219 | ```matlab 220 | cd Image_Processing 221 | Image_Processing 222 | ``` 223 | 224 | ### 使用流程 225 | 226 | 1. **加载图像**: 点击 `Open` 按钮选择图像文件 227 | 2. **应用处理**: 选择所需的图像处理功能 228 | 3. **参数调节**: 使用滑块实时调整参数 229 | 4. **查看结果**: 对比原图与处理结果,查看波形和直方图 230 | 5. **保存图像**: 点击 `Save` 按钮导出处理结果 231 | 6. **重置操作**: 点击 `Reset` 恢复到原始图像 232 | 233 | ## 📊 项目结构 | Project Structure 234 | 235 | ``` 236 | MATLAB_Image_Processing/ 237 | ├── LICENSE # MIT 开源协议 238 | ├── README.md # 项目文档 239 | ├── Image_Processing/ 240 | │ ├── Image_Processing.m # 主程序 (869 行) 241 | │ │ ├── GUI 初始化 242 | │ │ ├── 回调函数 (30+ 个) 243 | │ │ ├── 可视化更新函数 244 | │ │ └── 工具函数 245 | │ └── Image_Processing.fig # GUIDE 界面设计文件 246 | └── images/ 247 | └── main.png # 应用截图 248 | ``` 249 | 250 | ## 🎓 技术特点 | Technical Highlights 251 | 252 | ### 设计模式 253 | - **MVC 架构**: View (fig) + Controller (callbacks) + Model (handles) 254 | - **事件驱动**: 基于 MATLAB 的回调机制 255 | - **状态模式**: 使用 Enable/Visible 属性管理 UI 状态 256 | 257 | ### 代码质量 258 | - **模块化**: 每个功能独立的回调函数 259 | - **可复用**: 封装的可视化更新函数 260 | - **健壮性**: 类型检测和错误警告 261 | - **可维护**: 清晰的代码结构和注释 262 | 263 | ### 用户体验 264 | - **渐进式启用**: 未加载图像前禁用处理功能 265 | - **即时反馈**: 所有操作实时更新显示 266 | - **进度指示**: 加载图像时显示进度条 267 | - **友好提示**: 不合理操作时弹出警告对话框 268 | 269 | ## 🔮 未来展望 | Future Work 270 | 271 | ### 计划功能 272 | - [ ] 批量处理模式 273 | - [ ] 撤销/重做栈 (Undo/Redo) 274 | - [ ] 更多分割算法 (Otsu, K-means, Watershed) 275 | - [ ] 形态学操作 (腐蚀、膨胀、开闭运算) 276 | - [ ] 频域滤波 (FFT, 频谱分析) 277 | - [ ] 自定义卷积核编辑器 278 | - [ ] 图像质量评估指标 (PSNR, SSIM) 279 | - [ ] 导出处理流程为脚本 280 | 281 | ### 优化方向 282 | - 多线程加速大图处理 283 | - 更精细的参数调节 (输入框 + 滑块) 284 | - 支持更多图像格式 (TIFF, RAW) 285 | - 添加操作历史记录面板 286 | 287 | ## 📚 参考资料 | References 288 | 289 | - Gonzalez, R. C., & Woods, R. E. (2018). *Digital Image Processing* (4th ed.) 290 | - MATLAB Image Processing Toolbox Documentation 291 | - Canny, J. (1986). "A Computational Approach to Edge Detection" 292 | 293 | ## 📄 许可证 | License 294 | 295 | 本项目采用 [MIT License](LICENSE) 开源协议 296 | 297 | ``` 298 | Copyright (c) 2023 Temmie 299 | ``` 300 | 301 | ## 👨‍💻 作者 | Author 302 | 303 | **Temmie** - [@OlyMarco](https://github.com/OlyMarco) 304 | 305 | ## 🙏 致谢 | Acknowledgments 306 | 307 | 感谢所有为数字图像处理领域做出贡献的研究者和工程师 308 | 309 | --- 310 | 311 | ⭐ 如果这个项目对您有帮助,请给个 Star! 312 | 313 | 💡 欢迎提交 Issue 和 Pull Request! 314 | -------------------------------------------------------------------------------- /Image_Processing/Image_Processing.m: -------------------------------------------------------------------------------- 1 | function varargout = Image_Processing(varargin) 2 | % Begin initialization code - DO NOT EDIT 3 | gui_Singleton = 1; 4 | gui_State = struct('gui_Name', mfilename, ... 5 | 'gui_Singleton', gui_Singleton, ... 6 | 'gui_OpeningFcn', @Image_Processing_OpeningFcn, ... 7 | 'gui_OutputFcn', @Image_Processing_OutputFcn, ... 8 | 'gui_LayoutFcn', [] , ... 9 | 'gui_Callback', []); 10 | if nargin && ischar(varargin{1}) 11 | gui_State.gui_Callback = str2func(varargin{1}); 12 | end 13 | 14 | if nargout 15 | [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); 16 | else 17 | gui_mainfcn(gui_State, varargin{:}); 18 | end 19 | % End initialization code - DO NOT EDIT 20 | 21 | 22 | % --- Executes just before Image_Processing is made visible. 23 | function Image_Processing_OpeningFcn(hObject, ~, handles, varargin) 24 | handles.output = hObject; 25 | handles.h = 0; 26 | handles.v = 0; 27 | handles.r = 0; 28 | % 未打开图片时功能隐藏 29 | set(handles.save,'Enable','off'); 30 | set(handles.reset,'Enable','off'); 31 | set(handles.exit,'Enable','off'); 32 | 33 | set(handles.Flip_Side2Side,'Enable','off'); 34 | set(handles.Upside2Down,'Enable','off'); 35 | set(handles.imgGrey,'Enable','off'); 36 | 37 | set(handles.hTranslation,'Enable','off'); 38 | set(handles.vTranslation,'Enable','off'); 39 | set(handles.imgResize,'Enable','off'); 40 | set(handles.imgRotate,'Enable','off'); 41 | 42 | set(handles.Sobel,'Enable','off'); 43 | set(handles.Roberts,'Enable','off'); 44 | set(handles.Prewitt,'Enable','off'); 45 | set(handles.LOG,'Enable','off'); 46 | set(handles.Canny,'Enable','off'); 47 | 48 | set(handles.averFiltering,'Enable','off'); 49 | set(handles.midFiltering,'Enable','off'); 50 | set(handles.gaussFilter,'Enable','off'); 51 | 52 | set(handles.imgAdd,'Enable','off'); 53 | set(handles.imgFuse,'Enable','off'); 54 | 55 | set(handles.Histeq,'Enable','off'); 56 | set(handles.contrastLighten,'Enable','off'); 57 | set(handles.contrastDarken,'Enable','off'); 58 | 59 | set(handles.imgSeg,'Enable','off'); 60 | 61 | set(handles.text121,'Enable','off'); 62 | set(handles.text122,'Enable','off'); 63 | set(handles.text123,'Enable','off'); 64 | set(handles.text124,'Enable','off'); 65 | set(handles.text2,'Enable','off'); 66 | 67 | set(handles.g11,'Visible','off'); 68 | set(handles.g12,'Visible','off'); 69 | set(handles.g21,'Visible','off'); 70 | set(handles.g22,'Visible','off'); 71 | set(handles.g23,'Visible','off'); 72 | % Update handles structure 73 | guidata(hObject, handles); 74 | 75 | % UIWAIT makes Image_Processing wait for user response (see UIRESUME) 76 | % uiwait(handles.figure1); 77 | 78 | 79 | % --- Outputs from this function are returned to the command line. 80 | function varargout = Image_Processing_OutputFcn(~, ~, handles) 81 | % varargout cell array for returning output args (see VARARGOUT); 82 | % hObject handle to figure 83 | % eventdata reserved - to be defined in a future version of MATLAB 84 | % handles structure with handles and user data (see GUIDATA) 85 | 86 | % Get default command line output from handles structure 87 | varargout{1} = handles.output; 88 | % 示波器g22彩色图象更新函数 89 | function gUpdate22(handles) 90 | r = handles.img(:, :, 1); 91 | g = handles.img(:, :, 2); 92 | b = handles.img(:, :, 3); 93 | x = size(r); 94 | x = (1: x(1,2)); 95 | r = r(1, :); 96 | g = g(1, :); 97 | b = b(1, :); 98 | axes(handles.g22); 99 | cla; 100 | plot(x,r,'r'); 101 | hold on 102 | plot(x, g, 'g'); 103 | plot(x, b, 'b'); 104 | hold off; 105 | 106 | ImageData1 = reshape(handles.img(:,:,1), [size(handles.img, 1) * size(handles.img, 2) 1]); 107 | ImageData2 = reshape(handles.img(:,:,2), [size(handles.img, 1) * size(handles.img, 2) 1]); 108 | ImageData3 = reshape(handles.img(:,:,3), [size(handles.img, 1) * size(handles.img, 2) 1]); 109 | [H1, X1] = hist(ImageData1, 1:5:256); 110 | [H2, X2] = hist(ImageData2, 1:5:256); 111 | [H3, X3] = hist(ImageData3, 1:5:256); 112 | axes(handles.g23); 113 | cla; 114 | hold on; 115 | plot(X1, H1, 'r'); 116 | plot(X2, H2, 'g'); 117 | plot(X3, H3, 'b'); 118 | axis([0 256 0 max([H1 H2 H3])]); 119 | 120 | % 示波器g23灰色图象更新函数 121 | function gUpdate23(handles) 122 | k = handles.img(:, :, 1); 123 | x = size(k); 124 | x = (1: x(1,2)); 125 | k = k(1, :); 126 | axes(handles.g22); 127 | cla; 128 | plot(x, k, 'k'); 129 | 130 | ImageData = reshape(handles.img, [size(handles.img, 1) * size(handles.img, 2) 1]); 131 | [H, X] = hist(ImageData, 1:5:256); 132 | axes(handles.g23); 133 | cla; 134 | hold on; 135 | plot(X, H, 'k'); 136 | axis([0 256 0 max(H)]); 137 | 138 | % --- Executes on button press in open. 139 | function open_Callback(hObject, ~, handles) 140 | % 打开按钮 141 | [file, path]=uigetfile({'*.jpg';'*.bmp';'*.jpeg';'*.png'}, 'Open'); 142 | if file==0 143 | warndlg('Choose an image...') ; 144 | else 145 | 146 | image=[path file]; 147 | handles.file=image; 148 | % 打开图片后功能显示 149 | set(handles.save,'Enable','on'); 150 | set(handles.reset,'Enable','on'); 151 | set(handles.exit,'Enable','on'); 152 | 153 | set(handles.Flip_Side2Side,'Enable','on'); 154 | set(handles.Upside2Down,'Enable','on'); 155 | set(handles.imgGrey,'Enable','on'); 156 | 157 | set(handles.hTranslation,'Enable','on'); 158 | set(handles.vTranslation,'Enable','on'); 159 | set(handles.imgResize,'Enable','on'); 160 | set(handles.imgRotate,'Enable','on'); 161 | 162 | set(handles.Sobel,'Enable','on'); 163 | set(handles.Roberts,'Enable','on'); 164 | set(handles.Prewitt,'Enable','on'); 165 | set(handles.LOG,'Enable','on'); 166 | set(handles.Canny,'Enable','on'); 167 | 168 | set(handles.averFiltering,'Enable','on'); 169 | set(handles.midFiltering,'Enable','on'); 170 | set(handles.gaussFilter,'Enable','on'); 171 | 172 | set(handles.imgAdd,'Enable','on'); 173 | set(handles.imgFuse,'Enable','on'); 174 | 175 | set(handles.Histeq,'Enable','on'); 176 | set(handles.contrastLighten,'Enable','on'); 177 | set(handles.contrastDarken,'Enable','on'); 178 | 179 | set(handles.Histeq,'Enable','on'); 180 | set(handles.imgAdd,'Enable','on'); 181 | 182 | set(handles.imgSeg,'Enable','on'); 183 | 184 | set(handles.text121,'Enable','on'); 185 | set(handles.text122,'Enable','on'); 186 | set(handles.text123,'Enable','on'); 187 | set(handles.text124,'Enable','on'); 188 | set(handles.text2,'Enable','on'); 189 | 190 | set(handles.g11,'Visible','on'); 191 | set(handles.g12,'Visible','on'); 192 | set(handles.g21,'Visible','on'); 193 | set(handles.g22,'Visible','on'); 194 | set(handles.g23,'Visible','on'); 195 | 196 | set(handles.open,'Enable','off'); 197 | 198 | handles.img=imread(image); 199 | handles.i=imread(image); 200 | % 进度条功能 201 | h = waitbar(0,'Waiting...'); 202 | steps = 100; 203 | for step = 1:steps 204 | waitbar(step / steps) 205 | end 206 | close(h) 207 | cla; 208 | imshow(handles.img); 209 | axes(handles.g11); 210 | imshow(handles.img); 211 | axes(handles.g12); 212 | 213 | cla; 214 | imshow(handles.img); 215 | guidata(hObject,handles); 216 | end 217 | 218 | 219 | % 示波器g21更新 220 | mysize=size(handles.img); 221 | if numel(mysize)>2 222 | r=handles.i(:,:,1); 223 | g=handles.i(:,:,2); 224 | b=handles.i(:,:,3); 225 | x=size(r); 226 | x=(1:x(1,2)); 227 | r=r(1,:); 228 | g=g(1,:); 229 | b=b(1,:); 230 | axes(handles.g21); 231 | cla; 232 | plot(x,r,'r'); 233 | hold on 234 | plot(x,g,'g'); 235 | plot(x,b,'b'); 236 | set(gca,'xtick',-inf:inf:inf); 237 | hold off; 238 | else 239 | k=handles.img(:,:,1); 240 | x=size(k); 241 | x=(1:x(1,2)); 242 | k=k(1,:); 243 | axes(handles.g21); 244 | cla; 245 | plot(x,k,'k'); 246 | end 247 | 248 | guidata(hObject,handles); 249 | 250 | mysize = size(handles.img); 251 | if numel(mysize)>2 252 | gUpdate22(handles) 253 | else 254 | gUpdate23(handles) 255 | end 256 | 257 | % hObject handle to open (see GCBO) 258 | % eventdata reserved - to be defined in a future version of MATLAB 259 | % handles structure with handles and user data (see GUIDATA) 260 | 261 | % --- Executes on button press in save. 262 | function save_Callback(~, ~, handles) 263 | % 保存按钮 264 | [file, path]= uiputfile('*.jpg','Save Image as'); 265 | if file==0 266 | warndlg('No change...') ; 267 | else 268 | save = [path file]; 269 | imwrite(handles.img, save, 'jpg'); 270 | end 271 | % hObject handle to save (see GCBO) 272 | % eventdata reserved - to be defined in a future version of MATLAB 273 | % handles structure with handles and user data (see GUIDATA) 274 | 275 | 276 | % --- Executes on button press in reset. 277 | function reset_Callback(hObject, ~, handles) 278 | % 重置按钮 279 | handles.img = handles.i; 280 | axes(handles.g12); 281 | cla; 282 | imshow(handles.img); 283 | guidata(hObject,handles); 284 | mysize = size(handles.img); 285 | if numel(mysize)>2 286 | gUpdate22(handles) 287 | else 288 | gUpdate23(handles) 289 | end 290 | 291 | % hObject handle to reset (see GCBO) 292 | % eventdata reserved - to be defined in a future version of MATLAB 293 | % handles structure with handles and user data (see GUIDATA) 294 | 295 | 296 | % --- Executes on button press in exit. 297 | function exit_Callback(~, ~, ~) 298 | % 退出按钮 299 | close all; 300 | 301 | % hObject handle to exit (see GCBO) 302 | % eventdata reserved - to be defined in a future version of MATLAB 303 | % handles structure with handles and user data (see GUIDATA) 304 | 305 | 306 | % --- Executes during object creation, after setting all properties. 307 | function g11_CreateFcn(~, ~, ~) 308 | % hObject handle to g11 (see GCBO) 309 | % eventdata reserved - to be defined in a future version of MATLAB 310 | % handles empty - handles not created until after all CreateFcns called 311 | function g11_DeleteFcn(~, ~, ~) 312 | % Hint: place code in OpeningFcn to populate g11 313 | 314 | 315 | % --- Executes during object creation, after setting all properties. 316 | function g12_CreateFcn(~, ~, ~) 317 | % hObject handle to g12 (see GCBO) 318 | % eventdata reserved - to be defined in a future version of MATLAB 319 | % handles empty - handles not created until after all CreateFcns called 320 | 321 | % Hint: place code in OpeningFcn to populate g12 322 | 323 | 324 | % --- Executes during object creation, after setting all properties. 325 | function g21_CreateFcn(~, ~, ~) 326 | % hObject handle to g21 (see GCBO) 327 | % eventdata reserved - to be defined in a future version of MATLAB 328 | % handles empty - handles not created until after all CreateFcns called 329 | 330 | % Hint: place code in OpeningFcn to populate g21 331 | 332 | 333 | % --- Executes during object creation, after setting all properties. 334 | function g22_CreateFcn(~, ~, ~) 335 | % hObject handle to g22 (see GCBO) 336 | % eventdata reserved - to be defined in a future version of MATLAB 337 | % handles empty - handles not created until after all CreateFcns called 338 | 339 | % Hint: place code in OpeningFcn to populate g22 340 | 341 | 342 | % --- Executes during object creation, after setting all properties. 343 | function g23_CreateFcn(~, ~, ~) 344 | % hObject handle to g23 (see GCBO) 345 | % eventdata reserved - to be defined in a future version of MATLAB 346 | % handles empty - handles not created until after all CreateFcns called 347 | 348 | % Hint: place code in OpeningFcn to populate g23 349 | 350 | 351 | % --- Executes on slider movement. 352 | function hTranslation_Callback(hObject, ~, handles) 353 | % 水平平移 354 | h = (get(hObject,'Value')); 355 | V = [h - handles.h, 0]; 356 | handles.h = h; 357 | handles.img = imtranslate(handles.img, V); 358 | axes(handles.g12); 359 | cla; 360 | imshow(handles.img) 361 | guidata(hObject, handles); 362 | mysize = size(handles.img); 363 | if numel(mysize)>2 364 | gUpdate22(handles) 365 | else 366 | gUpdate23(handles) 367 | end 368 | 369 | % hObject handle to hTranslation (see GCBO) 370 | % eventdata reserved - to be defined in a future version of MATLAB 371 | % handles structure with handles and user data (see GUIDATA) 372 | 373 | % Hints: get(hObject,'Value') returns position of slider 374 | % get(hObject,'Min') and get(hObject,'Max') to determine range of slider 375 | 376 | 377 | % --- Executes on slider movement. 378 | function vTranslation_Callback(hObject, ~, handles) 379 | % 垂直平移 380 | v = (get(hObject,'Value')); 381 | V = [0, v - handles.v]; 382 | handles.v = v; 383 | handles.img = imtranslate(handles.img, V); 384 | axes(handles.g12); 385 | cla; 386 | imshow(handles.img) 387 | guidata(hObject, handles); 388 | mysize = size(handles.img); 389 | if numel(mysize)>2 390 | gUpdate22(handles) 391 | else 392 | gUpdate23(handles) 393 | end 394 | 395 | % hObject handle to hTranslation (see GCBO) 396 | % eventdata reserved - to be defined in a future version of MATLAB 397 | % handles structure with handles and user data (see GUIDATA) 398 | 399 | % Hints: get(hObject,'Value') returns position of slider 400 | % get(hObject,'Min') and get(hObject,'Max') to determine range of slider 401 | 402 | 403 | % --- Executes during object creation, after setting all properties. 404 | function hTranslation_CreateFcn(hObject, ~, ~) 405 | % hObject handle to hTranslation (see GCBO) 406 | % eventdata reserved - to be defined in a future version of MATLAB 407 | % handles empty - handles not created until after all CreateFcns called 408 | 409 | % Hint: slider controls usually have a light gray background. 410 | if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) 411 | set(hObject,'BackgroundColor',[.9 .9 .9]); 412 | end 413 | 414 | 415 | % --- Executes during object creation, after setting all properties. 416 | function vTranslation_CreateFcn(hObject, ~, ~) 417 | % hObject handle to hTranslation (see GCBO) 418 | % eventdata reserved - to be defined in a future version of MATLAB 419 | % handles empty - handles not created until after all CreateFcns called 420 | 421 | % Hint: slider controls usually have a light gray background. 422 | if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) 423 | set(hObject,'BackgroundColor',[.9 .9 .9]); 424 | end 425 | 426 | 427 | % --- Executes on slider movement. 428 | function imgRotate_Callback(hObject, ~, handles) 429 | % 图像旋转 430 | r = (get(hObject,'Value')); 431 | handles.img = imrotate(handles.i, r); 432 | axes(handles.g12); 433 | cla; 434 | imshow(handles.img); 435 | guidata(hObject, handles) 436 | mysize = size(handles.img); 437 | if numel(mysize)>2 438 | gUpdate22(handles) 439 | else 440 | gUpdate23(handles) 441 | end 442 | 443 | % hObject handle to imgRotate (see GCBO) 444 | % eventdata reserved - to be defined in a future version of MATLAB 445 | % handles structure with handles and user data (see GUIDATA) 446 | 447 | % Hints: get(hObject,'Value') returns position of slider 448 | % get(hObject,'Min') and get(hObject,'Max') to determine range of slider 449 | 450 | 451 | % --- Executes during object creation, after setting all properties. 452 | function imgRotate_CreateFcn(hObject, ~, ~) 453 | % hObject handle to imgRotate (see GCBO) 454 | % eventdata reserved - to be defined in a future version of MATLAB 455 | % handles empty - handles not created until after all CreateFcns called 456 | 457 | % Hint: slider controls usually have a light gray background. 458 | if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) 459 | set(hObject,'BackgroundColor',[.9 .9 .9]); 460 | end 461 | 462 | 463 | % --- Executes on button press in gaussFilter. 464 | function gaussFilter_Callback(hObject, ~, handles) 465 | % 高斯滤波 466 | hsize=[8 8]; 467 | sigma=1.7; 468 | h = fspecial('gaussian', hsize, sigma); 469 | handles.img=imfilter(handles.img, h, 'replicate'); 470 | axes(handles.g12); cla; imshow(handles.img); 471 | guidata(hObject,handles); 472 | mysize=size(handles.img); 473 | if numel(mysize)>2 474 | gUpdate22(handles) 475 | else 476 | gUpdate23(handles) 477 | end 478 | 479 | % hObject handle to gaussFilter (see GCBO) 480 | % eventdata reserved - to be defined in a future version of MATLAB 481 | % handles structure with handles and user data (see GUIDATA) 482 | 483 | 484 | % --- Executes on button press in averFiltering. 485 | function averFiltering_Callback(hObject, ~, handles) 486 | % 均值滤波 487 | h=fspecial('average'); 488 | handles.img=imfilter(handles.img, h, 'replicate'); 489 | axes(handles.g12); 490 | cla; 491 | imshow(handles.img) 492 | guidata(hObject,handles); 493 | mysize=size(handles.img); 494 | if numel(mysize)>2 495 | gUpdate22(handles) 496 | else 497 | gUpdate23(handles) 498 | end 499 | 500 | % hObject handle to averFiltering (see GCBO) 501 | % eventdata reserved - to be defined in a future version of MATLAB 502 | % handles structure with handles and user data (see GUIDATA) 503 | 504 | 505 | % --- Executes on button press in midFiltering. 506 | function midFiltering_Callback(hObject, ~, handles) 507 | % 中值滤波 508 | r = medfilt2(handles.img(:,:,1)); 509 | g = medfilt2(handles.img(:,:,2)); 510 | b = medfilt2(handles.img(:,:,3)); 511 | handles.img=cat(3, r, g, b); 512 | axes(handles.g12); cla; imshow(handles.img); 513 | guidata(hObject,handles); 514 | mysize=size(handles.img); 515 | if numel(mysize)>2 516 | gUpdate22(handles) 517 | else 518 | gUpdate23(handles) 519 | end 520 | 521 | % hObject handle to midFiltering (see GCBO) 522 | % eventdata reserved - to be defined in a future version of MATLAB 523 | % handles structure with handles and user data (see GUIDATA) 524 | 525 | 526 | % --- Executes on button press in Sobel. 527 | function Sobel_Callback(hObject, ~, handles) 528 | % Sobel边缘检测 529 | mysize = size(handles.img); 530 | if numel(mysize)>2 531 | handles.img=rgb2gray(handles.img); 532 | end 533 | handles.img=edge(handles.img,'sobel'); 534 | axes(handles.g12); 535 | cla; 536 | imshow(handles.img); 537 | guidata(hObject,handles); 538 | gUpdate23(handles); 539 | 540 | % hObject handle to Sobel (see GCBO) 541 | % eventdata reserved - to be defined in a future version of MATLAB 542 | % handles structure with handles and user data (see GUIDATA) 543 | 544 | 545 | % --- Executes on button press in Roberts. 546 | function Roberts_Callback(hObject, ~, handles) 547 | % Roberts边缘检测 548 | mysize = size(handles.img); 549 | if numel(mysize)>2 550 | handles.img=rgb2gray(handles.img); 551 | end 552 | handles.img=edge(handles.img, 'roberts'); 553 | axes(handles.g12); 554 | cla; 555 | imshow(handles.img); 556 | guidata(hObject,handles); 557 | gUpdate23(handles); 558 | 559 | % hObject handle to Roberts (see GCBO) 560 | % eventdata reserved - to be defined in a future version of MATLAB 561 | % handles structure with handles and user data (see GUIDATA) 562 | 563 | 564 | % --- Executes on button press in Prewitt. 565 | function Prewitt_Callback(hObject, ~, handles) 566 | % Prewitt边缘检测 567 | mysize = size(handles.img); 568 | if numel(mysize)>2 569 | handles.img=rgb2gray(handles.img); 570 | end 571 | handles.img = edge(handles.img,'prewitt'); 572 | axes(handles.g12); 573 | cla; 574 | imshow(handles.img); 575 | guidata(hObject,handles); 576 | gUpdate23(handles); 577 | 578 | % hObject handle to Prewitt (see GCBO) 579 | % eventdata reserved - to be defined in a future version of MATLAB 580 | % handles structure with handles and user data (see GUIDATA) 581 | 582 | 583 | % --- Executes on button press in LOG. 584 | function LOG_Callback(hObject, ~, handles) 585 | % LOG边缘检测 586 | mysize = size(handles.img); 587 | if numel(mysize)>2 588 | handles.img=rgb2gray(handles.img); 589 | end 590 | handles.img=edge(handles.img,'log'); 591 | axes(handles.g12); 592 | cla; 593 | imshow(handles.img); 594 | guidata(hObject, handles); 595 | gUpdate23(handles) 596 | 597 | % hObject handle to LOG (see GCBO) 598 | % eventdata reserved - to be defined in a future version of MATLAB 599 | % handles structure with handles and user data (see GUIDATA) 600 | 601 | 602 | % --- Executes on button press in Canny. 603 | function Canny_Callback(hObject, ~, handles) 604 | 605 | mysize=size(handles.img); 606 | if numel(mysize)>2 607 | handles.img=rgb2gray(handles.img); 608 | end 609 | handles.img=edge(handles.img,'canny'); 610 | axes(handles.g12); 611 | cla; 612 | imshow(handles.img); 613 | guidata(hObject,handles); 614 | mysize = size(handles.img); 615 | if numel(mysize)>2 616 | gUpdate22(handles) 617 | else 618 | gUpdate23(handles) 619 | end 620 | 621 | % hObject handle to Canny (see GCBO) 622 | % eventdata reserved - to be defined in a future version of MATLAB 623 | % handles structure with handles and user data (see GUIDATA) 624 | 625 | 626 | % --- Executes on button press in imgAdd. 627 | function imgAdd_Callback(hObject, ~, handles) 628 | % 图像叠加 629 | [file, path] = uigetfile({'*.jpg';'*.bmp';'*.jpeg';'*.png'}, 'Open'); 630 | if file==0 631 | warndlg('No change...'); 632 | end 633 | alpha = 0.5; 634 | image = imread([path file]); 635 | handles.img = imadd(alpha.*handles.img, alpha.*imresize(image, 'OutputSize', [size(handles.img, 1), size(handles.img, 2)])); 636 | axes(handles.g12); 637 | cla; 638 | imshow(handles.img); 639 | guidata(hObject, handles); 640 | mysize = size(handles.img); 641 | if numel(mysize)>2 642 | gUpdate22(handles) 643 | else 644 | gUpdate23(handles) 645 | end 646 | 647 | % hObject handle to imgAdd (see GCBO) 648 | % eventdata reserved - to be defined in a future version of MATLAB 649 | % handles structure with handles and user data (see GUIDATA) 650 | 651 | % --- Executes on button press in contrastLighten. 652 | function contrastLighten_Callback(hObject, ~, handles) 653 | % 对比度亮增强 654 | if length(size(handles.img))>2 655 | handles.img = imadjust(handles.img, [0 0.9], []); 656 | axes(handles.g12); 657 | cla; 658 | imshow(handles.img) 659 | guidata(hObject, handles); 660 | mysize = size(handles.img); 661 | if numel(mysize)>2 662 | gUpdate22(handles) 663 | else 664 | gUpdate23(handles) 665 | end 666 | else 667 | warndlg('The image is grey...'); 668 | end 669 | 670 | % hObject handle to contrastLighten (see GCBO) 671 | % eventdata reserved - to be defined in a future version of MATLAB 672 | % handles structure with handles and user data (see GUIDATA) 673 | 674 | 675 | % --- Executes on button press in Histeq. 676 | function Histeq_Callback(hObject, ~, handles) 677 | % 直方图均衡化 678 | if length(size(handles.img))>2 679 | handles.img = histeq(handles.img); 680 | axes(handles.g12); 681 | cla; 682 | imshow(handles.img) 683 | guidata(hObject, handles); 684 | mysize = size(handles.img); 685 | if numel(mysize)>2 686 | gUpdate22(handles) 687 | else 688 | gUpdate23(handles) 689 | end 690 | else 691 | warndlg('The image is grey...'); 692 | end 693 | 694 | % hObject handle to Histeq (see GCBO) 695 | % eventdata reserved - to be defined in a future version of MATLAB 696 | % handles structure with handles and user data (see GUIDATA) 697 | 698 | 699 | % --- Executes on button press in imgGrey. 700 | function imgGrey_Callback(hObject, ~, handles) 701 | % 灰度 702 | if length(size(handles.img))>2 703 | handles.img = rgb2gray(handles.img); 704 | axes(handles.g12); 705 | cla; 706 | imshow(handles.img); 707 | guidata(hObject,handles); 708 | gUpdate23(handles); 709 | else 710 | warndlg("It's already a grey image...") ; 711 | end 712 | 713 | % hObject handle to imgGrey (see GCBO) 714 | % eventdata reserved - to be defined in a future version of MATLAB 715 | % handles structure with handles and user data (see GUIDATA) 716 | 717 | 718 | % --- Executes on button press in Upside2Down. 719 | function Upside2Down_Callback(hObject, ~, handles) 720 | % 垂直镜像 721 | handles.img = flipud(handles.img); 722 | axes(handles.g12); 723 | cla; 724 | imshow(handles.img); 725 | guidata(hObject, handles); 726 | mysize=size(handles.img); 727 | if numel(mysize)>2 728 | gUpdate22(handles) 729 | else 730 | gUpdate23(handles) 731 | end 732 | 733 | % hObject handle to Upside2Down (see GCBO) 734 | % eventdata reserved - to be defined in a future version of MATLAB 735 | % handles structure with handles and user data (see GUIDATA) 736 | 737 | 738 | % --- Executes on button press in Flip_Side2Side. 739 | function Flip_Side2Side_Callback(hObject, ~, handles) 740 | % 水平镜像 741 | handles.img = fliplr(handles.img); 742 | axes(handles.g12); 743 | cla; 744 | imshow(handles.img); 745 | guidata(hObject, handles); 746 | mysize=size(handles.img); 747 | if numel(mysize)>2 748 | gUpdate22(handles) 749 | else 750 | gUpdate23(handles) 751 | end 752 | 753 | % hObject handle to Flip_Side2Side (see GCBO) 754 | % eventdata reserved - to be defined in a future version of MATLAB 755 | % handles structure with handles and user data (see GUIDATA) 756 | 757 | 758 | % --- Executes on button press in contrastDarken. 759 | function contrastDarken_Callback(hObject, ~, handles) 760 | % 对比度暗增强 761 | if length(size(handles.img))>2 762 | handles.img = imadjust(handles.img, [0.1 1], []); 763 | axes(handles.g12); 764 | cla; 765 | imshow(handles.img) 766 | guidata(hObject, handles); 767 | mysize = size(handles.img); 768 | if numel(mysize)>2 769 | gUpdate22(handles) 770 | else 771 | gUpdate23(handles) 772 | end 773 | else 774 | warndlg('The image is grey...'); 775 | end 776 | 777 | % hObject handle to contrastDarken (see GCBO) 778 | % eventdata reserved - to be defined in a future version of MATLAB 779 | % handles structure with handles and user data (see GUIDATA) 780 | 781 | 782 | % --- Executes on button press in imgSeg. 783 | function imgSeg_Callback(hObject, ~, handles) 784 | % 阈值分割 785 | % if length(size(handles.img))>2 786 | T = (get(hObject, "Value")); 787 | handles.img = rgb2gray(handles.i) > T; 788 | axes(handles.g12); 789 | cla; 790 | imshow(handles.img) 791 | guidata(hObject, handles); 792 | gUpdate23(handles) 793 | % else 794 | % warndlg('The image is gfrey...'); 795 | % end 796 | 797 | % hObject handle to imgSeg (see GCBO) 798 | % eventdata reserved - to be defined in a future version of MATLAB 799 | % handles structure with handles and user data (see GUIDATA) 800 | % --- Executes during object creation, after setting all properties. 801 | function imgSeg_CreateFcn(~, ~, ~) 802 | % hObject handle to imgSeg (see GCBO) 803 | % eventdata reserved - to be defined in a future version of MATLAB 804 | % handles empty - handles not created until after all CreateFcns called 805 | 806 | 807 | % --- Executes on slider movement. 808 | function imgResize_Callback(hObject, ~, handles) 809 | % 图像缩放 810 | z = (get(hObject, "Value")); 811 | handles.img = imresize(handles.i, z ,'nearest'); 812 | [h, w, ~] = size(handles.i); 813 | [h2, w2, ~] = size(handles.img); 814 | handles.img = imcrop(handles.img, [(w2 - w) / 2 (h2 - h) / 2 w h]); 815 | axes(handles.g12); 816 | cla; 817 | imshow(handles.img) 818 | guidata(hObject, handles); 819 | mysize = size(handles.img); 820 | if numel(mysize)>2 821 | gUpdate22(handles) 822 | else 823 | gUpdate23(handles) 824 | end 825 | 826 | % hObject handle to imgResize (see GCBO) 827 | % eventdata reserved - to be defined in a future version of MATLAB 828 | % handles structure with handles and user data (see GUIDATA) 829 | 830 | % Hints: get(hObject,'Value') returns position of slider 831 | % get(hObject,'Min') and get(hObject,'Max') to determine range of slider 832 | 833 | 834 | % --- Executes during object creation, after setting all properties. 835 | function imgResize_CreateFcn(hObject, ~, ~) 836 | % hObject handle to imgResize (see GCBO) 837 | % eventdata reserved - to be defined in a future version of MATLAB 838 | % handles empty - handles not created until after all CreateFcns called 839 | 840 | % Hint: slider controls usually have a light gray background. 841 | if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) 842 | set(hObject,'BackgroundColor',[.9 .9 .9]); 843 | end 844 | 845 | 846 | % --- Executes on button press in imgFuse. 847 | function imgFuse_Callback(hObject, ~, handles) 848 | % 图像融合 849 | [file, path] = uigetfile({'*.jpg';'*.bmp';'*.jpeg';'*.png'}, 'Open'); 850 | if file==0 851 | warndlg('No change...'); 852 | end 853 | image = imread([path file]); 854 | handles.img = imfuse(handles.img, image, 'blend'); 855 | axes(handles.g12); 856 | cla; 857 | imshow(handles.img); 858 | guidata(hObject, handles); 859 | mysize = size(handles.img); 860 | if numel(mysize)>2 861 | gUpdate22(handles) 862 | else 863 | gUpdate23(handles) 864 | end 865 | 866 | % hObject handle to imgFuse (see GCBO) 867 | % eventdata reserved - to be defined in a future version of MATLAB 868 | % handles structure with handles and user data (see GUIDATA) 869 | --------------------------------------------------------------------------------