【图像处理速通】OpenCV 核心操作一网打尽:从像素到 SIFT 特征提取

发布时间:2026/7/29 10:34:46
【图像处理速通】OpenCV 核心操作一网打尽:从像素到 SIFT 特征提取 前言图像处理是计算机视觉的基石OpenCV 是这一领域最流行的工具库。本文旨在用一篇文章带你快速打通图像处理的常用操作从基础像素概念一路深入到轮廓检测、直方图均衡、傅里叶变换再到 Harris 角点和 SIFT 特征提取。无论你是初学者还是需要快速复习这篇“速通指南”都能帮你高效梳理核心知识点。1. 图像的基础像素与颜色通道1.1 像素的本质计算机眼中的图像由像素构成每个像素本质上是一个数值这个数值表示亮度。对于最常见的 8 位图像范围是0~2550纯黑没有亮度255纯白最高亮度1.2 颜色通道彩色图像通常使用RGB三个颜色通道每个通道独立记录亮度。形状可以表示为[H, W, 3]。灰度图只有一个通道形状为[H, W]许多检测任务如轮廓、特征提取都先转为灰度图进行处理。2. 图像的读取、显示与保存2.1 读取图像pythonimport cv2 # 彩色模式读取默认 img_color cv2.imread(cat.jpg, cv2.IMREAD_COLOR) # 灰度模式读取 img_gray cv2.imread(cat.jpg, cv2.IMREAD_GRAYSCALE)OpenCV 默认读入的颜色顺序是BGR用matplotlib显示时需要转换。2.2 转灰度图如果已经读入彩色图可以随时转换pythonimg_gray cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)2.3 显示图像OpenCV 显示窗口pythondef cv_show(name, img): cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows()也可用matplotlib绘图pythonimport matplotlib.pyplot as plt plt.imshow(img[:,:,::-1]) # BGR 转 RGB plt.show()2.4 保存图像pythoncv2.imwrite(output.jpg, img)2.5 图像属性pythonprint(img.shape) # (高度, 宽度, 通道数) print(img.size) # 总像素数 H*W*C print(img.dtype) # 数据类型如 uint83. 视频读取pythonvc cv2.VideoCapture(test.mp4) while vc.isOpened(): ret, frame vc.read() if not ret: break cv2.imshow(video, frame) if cv2.waitKey(30) 0xFF 27: # 按 Esc 退出 break vc.release() cv2.destroyAllWindows()waitKey(30)表示每帧间隔 30ms对应约 33 fps流畅播放。4. 通道分离与合并4.1 分离pythonb, g, r cv2.split(img)4.2 合并pythonimg_merged cv2.merge((b, g, r))4.3 只保留某一通道将其他通道置 0例如只显示蓝色分量pythonblue_only img.copy() blue_only[:, :, 1] 0 # 绿通道置0 blue_only[:, :, 2] 0 # 红通道置05. 图像的数值运算与融合5.1 直接加法溢出取余pythonimg2 img 10 # 超过255会取模如 256 → 05.2 图像融合两张图像相加融合前需保证尺寸一致使用cv2.resize。pythonimg1 cv2.imread(1.jpg) img2 cv2.imread(2.jpg) img2 cv2.resize(img2, (img1.shape[1], img1.shape[0])) fusion cv2.addWeighted(img1, 0.6, img2, 0.4, 0) # 加权融合6. 图像边界填充python# top, bottom, left, right img_padded cv2.copyMakeBorder(img, 50, 50, 50, 50, cv2.BORDER_CONSTANT, value0)7. 阈值处理pythonret, binary cv2.threshold(src, thresh, maxval, type)常用typecv2.THRESH_BINARY大于阈值取 maxval否则 0cv2.THRESH_BINARY_INV反向cv2.THRESH_TRUNC截断cv2.THRESH_TOZERO小于阈值置零阈值操作常用于将灰度图转为二值图为后续轮廓检测做准备。8. 图像平滑滤波平滑旨在去除噪声为边缘检测等任务做准备。滤波方式函数特点均值滤波cv2.blur(img, (3,3))简单平均图像变模糊方框滤波cv2.boxFilter(img, -1, (3,3))若未归一化像素值会叠加通常需要归一化高斯滤波cv2.GaussianBlur(img, (3,3), 1)中心权重更大离中心越远的点影响越小中值滤波cv2.medianBlur(img, 3)用邻域像素中值替换适合椒盐噪声pythonblur cv2.blur(img, (5,5)) gaussian cv2.GaussianBlur(img, (5,5), 0) median cv2.medianBlur(img, 5)9. 形态学操作形态学主要用于处理二值图像提取形状或去除噪声。腐蚀(cv2.erode)边界向内收缩可去除细小噪点。膨胀(cv2.dilate)边界向外扩张可填补空洞。开运算与闭运算开运算先腐蚀后膨胀 → 去除毛刺、分离细小连接。闭运算先膨胀后腐蚀 → 填充空洞、连接邻近物体。pythonkernel np.ones((5,5), np.uint8) opening cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) closing cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)形态学梯度轮廓信息pythongradient cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) # 等价于 膨胀 - 腐蚀礼帽与黑帽礼帽原图 - 开运算 → 得到“刺”或亮区细节黑帽闭运算 - 原图 → 得到暗区轮廓pythontophat cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) blackhat cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)10. 图像梯度与边缘检测10.1 梯度算子Sobel 算子一阶微分抗噪较好Scharr 算子Sobel 的增强版核更大Laplacian 算子二阶微分对噪声敏感pythonsobelx cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize3) scharrx cv2.Scharr(img, cv2.CV_64F, 1, 0) laplacian cv2.Laplacian(img, cv2.CV_64F)10.2 Canny 边缘检测最经典的边缘检测算法步骤包括高斯滤波、梯度计算、非极大值抑制和双阈值筛选。pythonedges cv2.Canny(img, threshold150, threshold2150)11. 图像金字塔图像金字塔是同一图像不同分辨率的集合用于多尺度分析。11.1 高斯金字塔向下采样(cv2.pyrDown)尺寸减半先高斯模糊再去掉偶数行列。向上采样(cv2.pyrUp)尺寸加倍用 0 填充后高斯模糊。pythondown cv2.pyrUp(img) # 放大变模糊 up cv2.pyrDown(img) # 缩小11.2 拉普拉斯金字塔拉普拉斯金字塔由高斯金字塔层间相减得到更关注高频细节常用于图像融合。12. 轮廓检测轮廓检测要求输入为二值图像通常先灰度化再阈值分割。python# 寻找轮廓 contours, hierarchy cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 绘制轮廓会覆盖原图建议先复制 draw_img img.copy() res cv2.drawContours(draw_img, contours, -1, (0, 255, 0), 3) cv_show(Contours, res)轮廓特征pythoncnt contours[0] # 取第一个轮廓 area cv2.contourArea(cnt) # 面积 perimeter cv2.arcLength(cnt, True) # 周长True表示闭合 epsilon 0.1 * perimeter # 近似精度 approx cv2.approxPolyDP(cnt, epsilon, True) # 轮廓多边形近似13. 模板匹配将模板图像在待搜索图像上滑动计算匹配度。pythonresult cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(result) # 画出匹配区域 h, w template.shape[:2] top_left max_loc # 归一化相关系数匹配取最大值位置 bottom_right (top_left[0]w, top_left[1]h) cv2.rectangle(img, top_left, bottom_right, 255, 2)不同匹配方法TM_SQDIFF平方差最小、TM_CCORR_NORMED、TM_CCOEFF_NORMED推荐使用归一化方法结果更稳定。14. 直方图与均衡化14.1 计算直方图pythonhist cv2.calcHist([img], channels[0], maskNone, histSize[256], ranges[0, 256])14.2 Mask 操作只统计感兴趣区域的直方图pythonmask np.zeros(img.shape[:2], np.uint8) mask[100:300, 100:300] 255 masked_hist cv2.calcHist([img], [0], mask, [256], [0, 256])14.3 直方图均衡化全局均衡化增强对比度但可能丢失细节。pythonequ cv2.equalizeHist(gray_img)自适应均衡化(CLAHE)分块均衡限制对比度过度放大。pythonclahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) clahe_img clahe.apply(gray_img)15. 傅里叶变换傅里叶变换将图像从空间域转换到频率域。低频分量图像中变化缓慢的灰度分量如背景、大块区域高频分量变化剧烈的灰度分量如边缘、噪声低通滤波器保留低频抑制高频 → 图像变模糊高通滤波器保留高频抑制低频 → 提取边缘与细节pythonimport numpy as np f np.fft.fft2(gray) # 傅里叶变换 fshift np.fft.fftshift(f) # 将零频移到中心 # 设计低通/高通掩膜并相乘再做逆变换恢复图像...16. 图像特征检测16.1 Harris 角点检测角点是水平和垂直方向灰度都变化剧烈的点。基本思想是用一个小窗口在图像上滑动观察窗口内的灰度变化。pythongray np.float32(gray) dst cv2.cornerHarris(gray, blockSize2, ksize3, k0.04) img[dst 0.01*dst.max()] [0, 0, 255] # 标记角点16.2 SIFT 特征提取SIFT 具有尺度不变性和旋转不变性步骤包括构建尺度空间寻找 DoG 空间的极值点。定位真正的极值点泰勒展开精确定位消除边界响应。为关键点分配方向并用直方图统计邻域梯度生成特征描述符。旋转坐标轴以保证旋转不变性。注意SIFT 曾经受专利保护需在 opencv-contrib 中从cv2.xfeatures2d.SIFT_create()调用。但自 OpenCV 4.4.0 起专利到期SIFT 已回归主库可直接使用pythonsift cv2.SIFT_create() kp sift.detect(gray, None) # 检测关键点 kp, des sift.compute(gray, kp) # 计算描述符 # 或者一步到位 kp, des sift.detectAndCompute(gray, None) # 绘制关键点 img_kp cv2.drawKeypoints(img, kp, None, flagscv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) cv_show(SIFT, img_kp)结语本文从最基本的像素与通道起步逐步深入形态学、滤波、梯度、金字塔、轮廓、直方图、频域变换直到角点和 SIFT 特征检测覆盖了 OpenCV 图像处理的绝大多数高频操作。将这份“速通笔记”收为己用配合实际代码练习相信你能在短时间内建立起图像处理的完整知识框架。 速通不是终点而是起点。掌握这些核心轮子后你完全可以驾驭更复杂的视觉任务如目标检测、图像分割、全景拼接等。如果觉得有帮助欢迎点赞收藏让更多人一起速通图像处理