欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > OpenCV 进阶实战与技巧——图像处理的全面解析

OpenCV 进阶实战与技巧——图像处理的全面解析

2025/4/18 23:18:51 来源:https://blog.csdn.net/weixin_66485800/article/details/147126735  浏览:    关键词:OpenCV 进阶实战与技巧——图像处理的全面解析

在上篇文章中,我们一起迈入了 Python OpenCV 的奇妙世界,学习了图像的读取、显示和保存等基本操作:用Python和OpenCV开启图像处理魔法之旅-CSDN博客。今天,我们将继续深入,探索图像的各种变换、滤波、边缘检测以及更深入地理解图像的数据表示和属性。准备好进一步驾驭你手中的像素了吗?Let's go!

 

 

目录

一、图像数据基础

像素与数组表示

颜色空间

图像属性

二、几何变换与插值

平移

旋转

缩放

三、图像锐化与直方图处理

图像锐化

直方图处理

四、图像滤波与平滑

均值滤波

中值滤波

高斯滤波

 效果示意​编辑

含椒盐噪声的图像

均值滤波后的图像

中值滤波后的图像

高斯滤波后的图像

五、综合应用案例

结语:探索无止境的图像世界


一、图像数据基础

像素与数组表示

在 OpenCV 中,图像是以多维数组的形式存储的,其中每个元素即为图像的一个像素。对于彩色图像,默认采用 BGR 颜色顺序表示。例如,以下代码展示如何读取图像并访问其中某个像素的 B、G、R 值:

import cv2# 读取图像(确保路径正确)
img = cv2.imread("sample.jpg")# 获取图像的尺寸:高度、宽度、通道数
height, width, channels = img.shape
print("图像尺寸:", height, width, channels)# 访问图像的某个像素,例如 (x=100, y=50)
b, g, r = img[50, 100]
print("像素 (100,50) 的 BGR 值:", b, g, r)

颜色空间

除了默认的 BGR,OpenCV 支持多种颜色空间转换,如灰度、HSV、LAB 等。以下代码展示如何将彩色图像转换为灰度和 HSV 图像:

import cv2img = cv2.imread("sample.jpg")# 将 BGR 转换为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 将 BGR 转换为 HSV 图像
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)cv2.imshow("灰度图", gray_img)
cv2.imshow("HSV图", hsv_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像属性

图像属性包括尺寸、坐标以及数据类型,这些信息有助于我们了解图像内部结构。例如,img.shape 返回一个元组表示图像尺寸,而 img.dtype 则表示数据类型:

import cv2img = cv2.imread("sample.jpg")print("尺寸 (height, width, channels):", img.shape)
print("图像数据类型:", img.dtype)

 

二、几何变换与插值

几何变换主要用于对图像进行平移、旋转、缩放等操作。在这些变换过程中,插值方法决定了变换后图像的平滑程度,常用的插值方法有最近邻插值、双线性插值和立方插值等。

OpenCV图像坐标与常规的数学坐标有区别,左上角位置为坐标原点,X轴向左为正,Y轴向下为正

平移

利用仿射变换矩阵实现图像平移。下面代码将图像向右平移 100 像素,向下平移 50 像素:

import cv2
import numpy as npimg = cv2.imread("sample.jpg")
rows, cols = img.shape[:2]# 平移矩阵:tx 为 x 方向平移,ty 为 y 方向平移
M_translate = np.float32([[1, 0, 100], [0, 1, 50]])
translated_img = cv2.warpAffine(img, M_translate, (cols, rows),flags=cv2.INTER_LINEAR)  # INTER_LINEAR 为双线性插值cv2.imshow("平移效果", translated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • img.shape[:2]img.shape 返回一个元组,包含图像的行数、列数和通道数(对于彩色图像)。[:2] 表示取前两个元素,即行数和列数,并分别赋值给变量 rows 和 cols
  • np.float32([[1, 0, 100], [0, 1, 50]]):使用 numpy 的 float32 数据类型创建一个 2x3 的矩阵 M_translate,其中 t_x = 100 表示在 x 方向向右平移 100 个像素,t_y = 50 表示在 y 方向向下平移 50 个像素。
  • cv2.warpAffine 是 OpenCV 中用于进行仿射变换的函数。
  • 参数解释
    • img:输入的原始图像。
    • M_translate:前面创建的 2x3 仿射变换矩阵,用于描述平移操作。
    • (cols, rows):输出图像的大小,这里指定为与原始图像相同的大小。
    • flags=cv2.INTER_LINEAR:插值方法,cv2.INTER_LINEAR 表示使用双线性插值。在进行图像变换时,可能会出现新的像素位置不是整数的情况,需要通过插值方法来计算这些新位置的像素值。双线性插值是一种常用的插值方法,它通过对周围四个像素的值进行加权平均来计算新像素的值,能够得到较好的平滑效果。

旋转

利用 cv2.getRotationMatrix2D 得到旋转矩阵进行旋转操作,同时也可指定插值方法:

 

import cv2
import numpy as npimg = cv2.imread("sample.jpg")
rows, cols = img.shape[:2]center = (cols / 2, rows / 2)
angle = 45     # 旋转角度
scale = 1      # 缩放比例M_rotate = cv2.getRotationMatrix2D(center, angle, scale)
rotated_img = cv2.warpAffine(img, M_rotate, (cols, rows), flags=cv2.INTER_CUBIC)  # INTER_CUBIC 为立方插值cv2.imshow("旋转效果", rotated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • center:这是旋转的中心点。(cols / 2, rows / 2) 代表以图像的中心作为旋转点。cols 是图像的列数,rows 是图像的行数,将它们各自除以 2 就能得到图像的中心坐标。
  • angle:表示旋转的角度,这里设定为 45 度,意味着图像会逆时针旋转 45 度。若角度为负数,则图像会顺时针旋转。
  • scale:是缩放比例,值为 1 时表示不进行缩放,图像在旋转过程中大小保持不变。若 scale 大于 1,图像会放大;若小于 1,图像则会缩小。
  • cv2.getRotationMatrix2D 是 OpenCV 提供的一个函数,其作用是根据给定的旋转中心、旋转角度和缩放比例来生成一个 2x3 的仿射变换矩阵。
  • cv2.warpAffine 同样是 OpenCV 中用于进行仿射变换的函数,在前面图像平移的代码里也有使用。

缩放

利用 cv2.resize 进行图像缩放,同时指定不同的插值方法,以获得更高的缩放质量。

import cv2img = cv2.imread("sample.jpg")# 缩小图像(双线性插值)
scaled_down = cv2.resize(img, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)# 放大图像(立方插值效果更好)
scaled_up = cv2.resize(img, (0, 0), fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC)cv2.imshow("缩小图像", scaled_down)
cv2.imshow("放大图像", scaled_up)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

三、图像锐化与直方图处理

图像锐化

图像锐化是通过卷积核加强图像细节,常用方法是利用拉普拉斯增强或自定义卷积核。如下代码展示如何对图像进行锐化操作:

import cv2
import numpy as npimg = cv2.imread("sample.jpg")
kernel_sharpen = np.array([[-1, -1, -1],[-1, 9, -1],[-1, -1, -1]])sharpened_img = cv2.filter2D(img, -1, kernel_sharpen)cv2.imshow("锐化图像", sharpened_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 卷积核的作用:在图像处理中,卷积核(也叫滤波器)是一个小的矩阵,通过卷积操作可以对图像进行各种处理,像模糊、锐化等。锐化操作的目的是增强图像中物体的边缘和细节,让图像看起来更清晰。
  • 核元素的意义:这个 3x3 的卷积核 kernel_sharpen 中,中心元素为 9,周围元素为 -1。其原理是增强中心像素的权重,同时抑制周围像素的影响,这样就能增强图像中的高频部分(边缘和细节),从而达到锐化的效果。
  • cv2.filter2D 是 OpenCV 里用于进行二维卷积操作的函数。参数 -1 表示输出图像的数据类型和输入图像相同。如果指定为一个具体的数据类型,那么输出图像的数据类型就会按照指定的类型进行转换。

 

直方图处理

直方图可以反映图像灰度级分布,直方图均衡化能够改善图像对比度。以下代码展示如何计算直方图并进行均衡化处理:

import cv2
from matplotlib import pyplot as pltimg = cv2.imread("example.png", 0) 
# 读取灰度图,参数 0 表示以灰度模式读取图像,即图像的每个像素只有一个灰度值,取值范围是 0 到 255# 计算直方图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])# 显示直方图
plt.figure()
plt.title("直方图")
plt.xlabel("灰度级")
plt.ylabel("像素数")
plt.plot(hist)
plt.xlim([0, 256])
plt.show()# 直方图均衡化
equalized_img = cv2.equalizeHist(img)
cv2.imshow("junhen", equalized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • cv2.calcHist 是 OpenCV 中用于计算图像直方图的函数。
  • 参数解释
    • [img]:表示输入的图像列表,这里只有一个图像 img,所以用列表形式传入。
    • [0]:表示要计算直方图的通道索引。因为图像是灰度图,只有一个通道,所以索引为 0。如果是彩色图像(有 BGR 三个通道),可以分别传入 [0][1][2] 来计算蓝色、绿色、红色通道的直方图。
    • None:表示没有掩码图像。掩码图像可以用于指定只计算图像的一部分区域的直方图,这里不使用掩码,所以为 None
    • [256]:表示直方图的 bins(区间)数量。这里将灰度值范围 0 到 255 划分为 256 个区间,每个区间代表一个灰度级。
    • [0, 256]:表示灰度值的范围,即从 0 到 255。
  • 计算结果 hist 是一个包含 256 个元素的一维数组,每个元素对应一个灰度级的像素数量。

cv2.equalizeHist 是 OpenCV 中用于直方图均衡化的函数。直方图均衡化是一种图像增强技术,它通过重新分布图像的像素值,使图像的直方图尽可能地均匀分布,从而增强图像的对比度。 

 

 


四、图像滤波与平滑

图像滤波技术主要用于去除噪声和改善图像质量,常用方法有均值滤波、中值滤波和高斯滤波。

均值滤波

均值滤波通过求解窗口内像素的平均值来平滑图像,适用于低噪声场景

import cv2img = cv2.imread("sample.jpg")
mean_filtered = cv2.blur(img, (5, 5))cv2.imshow("均值滤波", mean_filtered)
cv2.waitKey(0)
cv2.destroyAllWindows()

中值滤波

中值滤波特别适合处理椒盐噪声,它通过窗口中位数替换中心像素值。

import cv2img = cv2.imread("sample.jpg")
median_filtered = cv2.medianBlur(img, 5)  # 注意窗口尺寸必须为奇数cv2.imshow("中值滤波", median_filtered)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

高斯滤波

高斯滤波以高斯分布权重对图像进行平滑处理,在去除噪声的同时较好地保留边缘信息

import cv2img = cv2.imread("sample.jpg")
gaussian_filtered = cv2.GaussianBlur(img, (5, 5), 0)cv2.imshow("高斯滤波", gaussian_filtered)
cv2.waitKey(0)
cv2.destroyAllWindows()

 效果示意

含椒盐噪声的图像

椒盐噪声表现为图像上随机分布的黑白噪点 ,这些噪点破坏了图像原本的像素分布,使图像看起来杂乱,掩盖了图像原本的特征和细节。

均值滤波后的图像

  • 噪声处理效果:相比含椒盐噪声的图像,噪声有一定程度的减少。均值滤波通过计算滤波核内像素的平均值来替代中心像素值,将噪点的灰度值分散到周围像素中,从而在一定程度上平滑了噪声。
  • 图像细节变化:但同时图像整体变得模糊,边缘也不够清晰。这是因为均值滤波对滤波核内所有像素一视同仁地平均,在去除噪声的同时,也使图像中原本清晰的边缘和细节被平均化,导致细节损失。

中值滤波后的图像

  • 噪声处理效果:能明显看出中值滤波对椒盐噪声有很好的抑制作用,大部分噪点被去除。中值滤波是将滤波核内像素灰度值排序后取中间值,椒盐噪声这种离散的极端灰度值(黑或白)很容易被周围正常像素值替代。
  • 图像细节变化:与均值滤波相比,图像的边缘等细节保留得更好,图像相对更清晰。因为中值滤波不是简单的平均,它更倾向于保留与周围像素相似的值,所以能较好地保护图像边缘。

高斯滤波后的图像

  • 噪声处理效果:对噪声有一定的平滑作用,能减少部分噪声干扰 。高斯滤波根据高斯分布对滤波核内像素进行加权平均,距离中心像素越近的像素权重越大。
  • 图像细节变化:但对于椒盐噪声的去除效果不如中值滤波明显,图像仍然存在较多噪点。同时,图像也有一定程度的模糊,这是由于高斯滤波的加权平均特性,会使图像的细节和边缘在一定程度上被平滑 。

 

 

五、综合应用案例

下面是一个综合示例,将几何变换、锐化、直方图处理、滤波和边缘检测组合在一起进行展示。可以根据需要调整各个步骤的参数,以观察不同的处理效果。

 

import cv2
import numpy as np# 1. 读取图像,获取图像属性
img = cv2.imread("sample.jpg")
height, width, channels = img.shape
print("图像尺寸:", height, width, channels)# 2. 几何变换:平移、旋转、缩放
M_translate = np.float32([[1, 0, 50], [0, 1, 30]])
img_translated = cv2.warpAffine(img, M_translate, (width, height), flags=cv2.INTER_LINEAR)center = (width / 2, height / 2)
M_rotate = cv2.getRotationMatrix2D(center, 30, 1)
img_rotated = cv2.warpAffine(img_translated, M_rotate, (width, height), flags=cv2.INTER_CUBIC)img_scaled = cv2.resize(img_rotated, (0, 0), fx=1.2, fy=1.2, interpolation=cv2.INTER_LINEAR)# 3. 图像锐化
kernel_sharpen = np.array([[-1, -1, -1],[-1, 9, -1],[-1, -1, -1]])
img_sharpened = cv2.filter2D(img_scaled, -1, kernel_sharpen)# 4. 直方图均衡化(先转换为灰度再处理)
gray_img = cv2.cvtColor(img_sharpened, cv2.COLOR_BGR2GRAY)
equalized_img = cv2.equalizeHist(gray_img)# 5. 图像滤波(以高斯滤波平滑为例)
smoothed_img = cv2.GaussianBlur(equalized_img, (5, 5), 0)# 6. 边缘检测——Sobel 与 Scharr
sobelx = cv2.Sobel(smoothed_img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(smoothed_img, cv2.CV_64F, 0, 1, ksize=3)
sobel_combined = cv2.addWeighted(cv2.convertScaleAbs(sobelx), 0.5,cv2.convertScaleAbs(sobely), 0.5, 0)scharrx = cv2.Scharr(smoothed_img, cv2.CV_64F, 1, 0)
schartry = cv2.Scharr(smoothed_img, cv2.CV_64F, 0, 1)
scharr_combined = cv2.addWeighted(cv2.convertScaleAbs(scharrx), 0.5,cv2.convertScaleAbs(schartry), 0.5, 0)# 7. 显示各阶段结果
cv2.imshow("原始图像", img)
cv2.imshow("几何变换后图像", img_scaled)
cv2.imshow("锐化图像", img_sharpened)
cv2.imshow("直方图均衡化", equalized_img)
cv2.imshow("平滑图像", smoothed_img)
cv2.imshow("Sobel 边缘", sobel_combined)
cv2.imshow("Scharr 边缘", scharr_combined)cv2.waitKey(0)
cv2.destroyAllWindows()

 

结语:探索无止境的图像世界

通过这第二篇博客,我们深入学习了 Python OpenCV 中更多关于图像处理和分析的技术,包括图像数据的表示、几何变换、锐化、滤波以及直方图处理。这些技能将为你进一步探索计算机视觉的更高级应用打下坚实的基础。

记住,学习是一个循序渐进的过程,动手实践至关重要。尝试使用不同的图像、不同的参数来运行这些代码,观察结果的变化,并思考为什么会产生这样的效果。在未来的文章中,我们将继续探索 OpenCV 的其他强大功能,例如目标检测、特征匹配等等。敬请期待!

如果这篇文章对你有所启发,期待你的点赞关注!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词