简介这份资源面向计算机视觉入门者、正在做毕设或课程设计的学生以及需要图像识别与模式识别实战练习的学习者聚焦图像分割与图像增强两类经典算法的Python复现。包内共28个文件以17个py源码为主辅以jpg、png测试图、md项目说明、txt辅助文档和pdf实验报告压缩包约2.46MB结构上区分了自写复现代码与参考程序便于对照学习。图像分割部分涵盖大津法OTSU、最大熵阈值分割、迭代阈值分割、Canny边缘检测及马尔可夫随机场其中带zixie后缀的文件为按论文复现的结果不带后缀的多为调用OpenCV的参考实现可用于效果与耗时对比图像增强部分则包含直方图均衡、CLAHE、单尺度SSR与多尺度MSR等。代码附详细注释并配有算法原理与实现效果说明已有1160人学习适合作为毕设或大作业的完整参考。1. 从一份图像处理复现包说起图像分割与图像增强到底怎么落地很多人第一次接触计算机视觉都是从「跑通一个图像分割或图像增强的 demo」开始的。你可能已经装好了 Python配好了 VS Code 或 PyCharm 环境甚至从国内源拉好了 opencv-python但真正打开一份图像处理算法的复现代码时还是会卡在几个地方这个算法到底解决什么问题、参数为什么这么设、分割出来的掩膜为什么是黑的、增强后的图为什么偏色。这份「图像分割、图像增强等多个图像处理算法的复现」源码包价值不在于它有多少行代码而在于它把底层视觉里最常被调用的几类算法——阈值分割、边缘检测、形态学处理、直方图均衡、Retinex 增强、小波变换增强——用可运行的 Python 脚本串了起来并且带详细注释和项目说明。它适合两类人一类是刚学完 Python 基础语法、想找一个计算机视觉大作业练手的新手另一类是做医学图像分割、广告牌图像分割系统这类具体任务需要回头补底层图像处理基本功的从业者。下面我按「先立住原理、再动手复现、最后讲坑」的顺序把这份复现包背后的技术路径拆开讲清楚。2. 图像分割算法的复现路径从阈值到 U-Net 的选型逻辑2.1 传统分割与深度学习分割的边界在哪图像分割算法大致分两条线。第一条是传统方法固定阈值、Otsu 自适应阈值、Canny 边缘加轮廓提取、分水岭算法、区域生长。第二条是深度学习方法U-Net、FCN、DeepLab 系列以及更早的 BP 神经网络图像分割思路。复现包里通常会把传统方法放在前面因为它们的依赖只有 numpy 和 opencv不需要 GPU跑起来快能让你直观看到「分割」这件事的本质——给每个像素打一个类别标签。选型上我一般这样判断如果目标是医学图像分割里的细胞、血管这类边界清晰、对比度稳定的目标传统阈值加形态学就能拿到能用的结果没必要上 U-Net如果目标是广告牌图像分割系统这种背景复杂、光照变化大的场景传统方法会频繁翻车这时候才需要深度学习。复现包的意义是让你先用传统方法建立对像素级操作的直觉再去看 U-Net 的 encoder-decoder 结构为什么能解决这些问题。2.2 用 OpenCV 跑通 Otsu 阈值分割的最小代码下面这段是复现包里最基础的一步Otsu 自动阈值分割。它不需要你手动指定阈值算法会根据图像灰度直方图自动找一个让类间方差最大的阈值。import cv2 import numpy as np # 读取图像第二个参数 0 表示以灰度模式读入 img cv2.imread(input.jpg, 0) # 高斯滤波去噪核大小 (5,5)标准差自动计算 blurred cv2.GaussianBlur(img, (5, 5), 0) # Otsu 阈值分割0 和 255 是占位cv2.THRESH_OTSU 会自动计算阈值 # 返回值 ret 是实际算出的阈值thresh 是二值化后的图像 ret, thresh cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 形态学开运算先腐蚀后膨胀去掉小的噪点 kernel np.ones((3, 3), np.uint8) opening cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations2) cv2.imwrite(otsu_result.png, opening) print(Otsu 自动阈值:, ret)逻辑说明先做高斯滤波是因为 Otsu 对噪声敏感椒盐噪声会让直方图出现假峰导致阈值偏移。cv2.threshold里传0和255只是形式参数真正起作用的是cv2.THRESH_OTSU标志。开运算的核大小(3,3)和迭代次数2是经验值核太大会把细小的目标结构腐蚀掉核太小去噪不干净。参数说明GaussianBlur的核必须是奇数(5,5)适合 500×500 到 2000×2000 分辨率的图如果图像本身很小比如 128×128用(3,3)就够。iterations控制形态学操作的重复次数次数越多去噪越强但目标边缘也会被磨圆。2.3 从传统分割过渡到 U-Net 的接口设计复现包里如果包含 U-Net 图像分割通常会有一个dataset.py负责把图像和掩膜配对读入一个unet.py定义网络结构一个train.py跑训练。传统方法和深度学习方法之间的接口关键在于掩膜的格式统一传统方法输出的是 0/255 的二值图U-Net 训练需要的是 0/1 的 float 标签并且形状要统一成(N, H, W, 1)。import numpy as np import cv2 def load_mask(path): # 以灰度读入掩膜 mask cv2.imread(path, 0) # 归一化到 0/1并扩展通道维度 mask mask.astype(np.float32) / 255.0 mask np.expand_dims(mask, axis-1) return mask def load_image(path, target_size(256, 256)): img cv2.imread(path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, target_size) img img.astype(np.float32) / 255.0 return img逻辑说明load_mask里除以 255 是为了把像素值压到 0 到 1 之间这是二分类分割的标准做法。np.expand_dims加一个通道维度是因为 Keras/TensorFlow 的卷积层要求输入是(batch, height, width, channels)四维。load_image里把 BGR 转成 RGB是因为 OpenCV 默认读入是 BGR 顺序而大多数预训练模型和可视化工具按 RGB 处理。参数说明target_size设成(256,256)是显存和精度的折中显存小于 6GB 时建议用 256显存充足可以用 512。如果原始图像长宽比差异大直接 resize 会拉伸目标更稳妥的做法是保持长边缩放到 256短边补零。3. 图像增强算法的复现直方图均衡、Retinex 与小波变换3.1 直方图均衡为什么会让彩色图偏色直方图均衡是图像增强里最容易复现、也最容易踩坑的算法。它的原理是把原始灰度直方图通过累积分布函数映射到均匀分布从而拉开灰度动态范围。对灰度图效果通常不错但直接对彩色图的 R、G、B 三个通道分别做均衡几乎必然偏色因为三个通道的直方图分布不同均衡后比例关系被破坏。复现包里常见的处理方式是先把图像转到 HSV 或 YCrCb 色彩空间只对亮度通道做均衡再转回 BGR。这样色相和饱和度不变只提升亮度对比度。import cv2 img cv2.imread(low_contrast.jpg) # 转到 YCrCb 色彩空间Y 是亮度通道 ycrcb cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb) y, cr, cb cv2.split(ycrcb) # 只对 Y 通道做直方图均衡 y_eq cv2.equalizeHist(y) # 合并后转回 BGR merged cv2.merge((y_eq, cr, cb)) result cv2.cvtColor(merged, cv2.COLOR_YCrCb2BGR) cv2.imwrite(hist_eq_result.jpg, result)逻辑说明cv2.split把三个通道拆开cv2.equalizeHist只接受单通道输入所以必须拆。均衡后cv2.merge按原顺序合并再转回 BGR。如果直接对 BGR 三通道分别均衡红色区域会明显偏橙蓝色区域会偏青。参数说明equalizeHist没有可调参数它的映射完全由输入直方图决定。如果图像本身已经有很宽的动态范围均衡后反而会过曝这时候应该改用 CLAHE限制对比度自适应直方图均衡它的clipLimit参数控制对比度增强上限常用值 2.0 到 4.0。3.2 Retinex 算法在雾天和低照度增强中的参数设置Retinex 的核心假设是图像等于光照分量乘以反射分量反射分量才是物体的固有属性。单尺度 RetinexSSR用高斯模糊估计光照多尺度 RetinexMSR用多个不同尺度的高斯核加权。复现包里如果包含基于 Retinex 算法的雾天/低照度图像增强复原系统关键参数就是高斯核的尺度。import cv2 import numpy as np def single_scale_retinex(img, sigma): # 转成 float避免溢出 img_float img.astype(np.float32) 1.0 # 高斯模糊估计光照分量 blur cv2.GaussianBlur(img_float, (0, 0), sigma) # 对数域相减得到反射分量 retinex np.log10(img_float) - np.log10(blur) return retinex def multi_scale_retinex(img, sigmas[15, 80, 250]): # 对每个通道分别做 MSR result np.zeros_like(img, dtypenp.float32) for sigma in sigmas: result single_scale_retinex(img, sigma) result / len(sigmas) # 归一化到 0-255 result cv2.normalize(result, None, 0, 255, cv2.NORM_MINMAX) return result.astype(np.uint8) img cv2.imread(foggy.jpg) enhanced multi_scale_retinex(img) cv2.imwrite(retinex_result.jpg, enhanced)逻辑说明1.0是为了避免对 0 取对数。cv2.GaussianBlur的核大小传(0,0)表示根据 sigma 自动计算核尺寸。MSR 用三个尺度小尺度保留细节大尺度保持颜色一致性中等尺度平衡。最后cv2.normalize把对数域的结果拉回 0 到 255。参数说明sigmas的取值和图像分辨率相关。500×500 左右的图用[15, 80, 250]比较稳如果图像更大比如 2000×2000小尺度要相应调大否则细节保留不足。sigma 太小会让结果出现光晕sigma 太大则增强效果不明显。3.3 小波变换图像增强的复现要点小波变换图像增强的思路和 Retinex 不同它把图像分解成低频近似分量和多个方向的高频细节分量然后对高频分量做非线性增强再重构回去。复现时通常用 PyWavelets 库。import pywt import cv2 import numpy as np img cv2.imread(input.jpg, 0).astype(np.float32) # 二级小波分解使用 db1 小波 coeffs pywt.wavedec2(img, db1, level2) # coeffs[0] 是低频近似coeffs[1:] 是各层高频 (cH, cV, cD) # 对高频系数做增强增益系数 1.5 enhanced_coeffs [coeffs[0]] for detail in coeffs[1:]: cH, cV, cD detail enhanced_coeffs.append((cH * 1.5, cV * 1.5, cD * 1.5)) # 重构 reconstructed pywt.waverec2(enhanced_coeffs, db1) reconstructed np.clip(reconstructed, 0, 255).astype(np.uint8) cv2.imwrite(wavelet_result.png, reconstructed)逻辑说明pywt.wavedec2返回的列表第一个元素是低频后面每个元素是一个三元组对应水平、垂直、对角三个方向的高频。增强时只放大高频低频保持不变这样能提升边缘和纹理的清晰度同时不改变整体亮度分布。pywt.waverec2做逆变换重构后的数值可能超出 0 到 255必须 clip。参数说明小波基db1是最简单的 Haar 小波计算快但方向选择性弱如果追求更好的增强效果可以换sym4或bior3.3。分解层数level2适合大多数中等分辨率图像层数越多能增强的细节尺度越粗但重构误差也会累积。增益系数1.5是保守值超过 2.0 容易在边缘产生振铃。4. 复现过程中最容易翻车的几个地方4.1 图像读进来是 None后面全报错现象cv2.imread返回None紧接着cv2.cvtColor或cv2.GaussianBlur抛出Assertion failed或src is not a numpy array。原因路径写错、文件名大小写不对、或者图像格式 OpenCV 不支持。Windows 下路径里的反斜杠\在 Python 字符串里是转义字符C:\new\test.jpg里的\n会被解释成换行。解决路径统一用正斜杠/或原始字符串rC:\new\test.jpg。读入后立刻加一句assert img is not None, 图像读取失败把错误定位在读图这一步而不是等到后面处理时才崩。4.2 分割掩膜全黑或全白现象Otsu 分割后输出的图要么全黑要么全白看不到目标轮廓。原因图像本身对比度极低或者目标区域和背景区域的灰度分布重叠严重Otsu 找不到有效的分割阈值。另一种可能是读入时用了彩色模式但后续按单通道处理通道数不匹配。解决先打印ret看自动算出的阈值是多少如果接近 0 或 255说明直方图没有明显双峰。这时候应该先做直方图均衡或 CLAHE 提升对比度再分割。同时确认cv2.imread的第二个参数是0保证是单通道灰度图。4.3 形态学操作把目标腐蚀没了现象开运算或闭运算之后原本能看到的细小目标消失了。原因形态学核太大或者迭代次数太多。开运算先腐蚀后膨胀腐蚀阶段会吃掉比核小的结构。解决把核从(5,5)降到(3,3)迭代次数从2降到1逐步试。如果目标本身就很细比如血管应该改用形态学细化或者直接跳过形态学用连通域分析去噪。4.4 Retinex 增强后颜色发灰、发白现象MSR 处理后的图像整体发灰饱和度下降看起来像蒙了一层雾。原因对数域相减后三个通道的数值范围不一致直接归一化会导致颜色失衡。另外 sigma 选择不当小尺度 sigma 太小会产生光晕大尺度 sigma 太大则增强不足。解决在 MSR 之后加一步颜色恢复用原始图像和增强结果的比值来校正每个通道。sigma 组合建议从[15, 80, 250]开始调每次只改一个值观察光晕和增强效果的变化。4.5 小波重构后图像尺寸和原图不一致现象pywt.waverec2输出的数组形状和输入图像差一个像素。原因小波分解时如果图像尺寸不是 2 的整数次幂边界处理会导致重构尺寸和原始尺寸有偏差。解决在分解前把图像 resize 到最近的 2 的幂次尺寸比如 512×512 或 1024×1024重构后再 resize 回原始尺寸。或者用pywt.wavedec2的modeperiodization参数它对边界处理更规整重构尺寸更容易对齐。5. 把复现包变成自己的项目验证方法与进阶习惯跑通复现包只是第一步真正让它变成你自己的东西需要一套验证方法。我一般会做三件事第一对同一张图用不同参数跑三遍把结果拼成对比图肉眼确认参数变化带来的影响是否符合预期第二用峰值信噪比PSNR和结构相似性SSIM做定量对比尤其是图像增强任务不能只看「好不好看」第三把每个算法的中间结果保存下来比如高斯模糊后的图、对数域相减后的图、小波分解后的高频系数图出问题时能快速定位是哪一步不对。from skimage.metrics import peak_signal_noise_ratio, structural_similarity import cv2 original cv2.imread(original.jpg, 0) enhanced cv2.imread(enhanced.jpg, 0) psnr peak_signal_noise_ratio(original, enhanced) ssim structural_similarity(original, enhanced) print(fPSNR: {psnr:.2f} dB, SSIM: {ssim:.4f})逻辑说明PSNR 衡量像素级误差值越高说明增强后的图与原图越接近但增强任务本身就是要改变像素所以 PSNR 只适合对比不同参数下的相对好坏不适合作为唯一标准。SSIM 从亮度、对比度、结构三个维度衡量相似性更接近人眼判断。参数说明peak_signal_noise_ratio默认data_range根据数据类型推断uint8 时是 255如果图像是 float 类型必须手动传data_range1.0。进阶方向上我建议把传统算法和深度学习串起来用 Retinex 或小波增强做预处理把增强后的图喂给 U-Net 做分割对比直接分割和增强后分割的 IoU 差异。这个对比实验能让你清楚看到底层图像处理对上层任务的实际贡献也是计算机视觉大作业里比较容易出彩的点。另一个习惯是每复现一个算法就在代码注释里写清楚「这个参数我调过哪几个值、哪个值效果最好、为什么」这份记录比代码本身更值钱。我自己踩过的最大坑就是早期只存代码不存参数记录过两个月回头再看完全想不起来当时为什么设成那个值只能重新试一遍。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
分布式事务从原理到落地:五大方案对比与选型指南 上周有个同事跑来问我:订单服务和库存服务拆开之后,用户下单成功,订单状态显示已支付,库存却扣了两次,数据库事务到底还能不能保证一致性?这个问题背后牵扯出来的东西,恰恰就是分布式事务的核心… · 2026/9/23 2:36:43
JSP+Servlet+MySQL学生选课系统:多角色登录与权限控制实战解析 简介:这是一套基于JSPServletMySQL开发的学生选课管理系统源码,面向需要完成课程设计、毕业设计或学习传统JavaWeb开发的初学者。系统支持教师与学生双角色登录,教师可管理学生、课程、选课信息并设置必修学分上下限,学生可在线选… · 2026/9/23 2:36:43
英语翻译词典性能优化:3个避坑指南让查询快10倍 英语翻译词典性能优化:3个避坑指南让查询快10倍 看了一堆教程还是不会写项目?别急,问题不在语法,而在你选错了数据结构。很多开发者在构建英语翻译词典时,默认用 dict 或 list… · 2026/9/23 2:36:43
质量文档模板实战:用 Quality Document 为 Agent 代码库建立可量化的质量快照 【免费下载链接】learn-harness-engineering Harness engineering beginner tutorial, from 0 to 1 项目地址: https://gitcode.com/gh_mirrors/le/learn-harness-engineering 点击查看 免费下载 导读: 在 Harness Engineering 实践中,代码库… · 2026/9/23 3:19:30
使用 LLM 命令行工具进行文本嵌入:从 CLI 命令到 Python API 的完整指南 使用 LLM 命令行工具进行文本嵌入:从 CLI 命令到 Python API 的完整指南 【免费下载链接】llm Access large language models from the command-line 项目地址: https://gitcode.com/gh_mirrors/llm/llm
本指南以 docs/embeddings/index.md 及其子页面&#… · 2026/9/23 3:19:24
3分钟吃透个人情况介绍源码解析与避坑指南 3分钟吃透个人情况介绍源码解析与避坑指南 官方文档往往长篇大论,让人一眼看过去就头晕,根本抓不住面试时该说什么。其实“个人情况介绍”在面试中不仅是礼仪,更是考察你逻辑表达与岗位匹配度的核心考点,其底层逻辑与代码中的 源码解析… · 2026/9/23 3:19:24
Rook 文件系统动态供给:从 CephFS 手动卷到 PVC/StorageClass 自动化编排 云原生存储容器编排运维 【免费下载链接】rook Storage Orchestration for Kubernetes 项目地址: https://gitcode.com/gh_mirrors/roo/rook 点击查看 免费下载 导读
本文围绕 Rook 仓库中的设计文档 dynamic-provision-filesystem.md 展开,深入剖析&q… · 2026/9/23 3:19:18
condition 条件步骤:在 Grafast 中构建布尔条件与流程控制 后端API网关 【免费下载链接】crystal 🔮 Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more! 项目地址: https://gitcode.com/gh_mirrors/cry/crystal 点击查看 免费下载 摘要
condition 是 Graf… · 2026/9/23 3:19:12
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29