数字图像处理
数字图像处理
认识
OpenCV加载的彩色图像处于BGR模式。但是Matplotlib以RGB模式显示。因此,如果使用OpenCV读取彩色图像,则Matplotlib中将无法正确显示彩色图像。有关更多详细信息,请参见练习。
读取图像
使用cv.imread()函数读取图像。图像应该在工作目录或图像的完整路径应给出。
第二个参数是一个标志,它指定了读取图像的方式。
- cv.IMREAD_COLOR: 加载彩色图像。任何图像的透明度都会被忽视。它是默认标志。
- cv.IMREAD_GRAYSCALE:以灰度模式加载图像
- cv.IMREAD_UNCHANGED:加载图像,包括alpha通道
注意 除了这三个标志,你可以分别简单地传递整数1、0或-1。
请参见下面的代码:
1 | import numpy as np |
显示图像
使用函数**cv.imshow()**在窗口中显示图像。窗口自动适合图像尺寸。
第一个参数是窗口名称,它是一个字符串。第二个参数是我们的对象。你可以根据需要创建任意多个窗口,但可以使用不同的窗口名称。
1 | cv.imshow("gezi",img) |
cv.waitKey()是一个键盘绑定函数。其参数是以毫秒为单位的时间。该函数等待任何键盘事件指定的毫秒。如果您在这段时间内按下任何键,程序将继续运行。如果0被传递,它将无限期地等待一次敲击键。它也可以设置为检测特定的按键
写入图像
使用函数cv.imwrite()保存图像。第一个参数是文件名,第二个参数是要保存的图像。 cv.imwrite('messigray.png',img)
这会将图像以PNG格式保存在工作目录中。
总结
1 | import numpy as np |
基本操作
使用Matplotlib
Matplotlib是Python的绘图库,可为你提供多种绘图方法。你将在接下来的文章中看到它们。在这里,你将学习如何使用Matplotlib显示图像。你可以使用Matplotlib缩放图像,保存图像等。
1 | import numpy as np |
plt的具体使用
在任何绘图之前,我们需要一个Figure对象,可以理解成我们需要一张画板才能开始绘图。
1 | import matplotlib.pyplot as plt |
在拥有Figure对象之后,在作画前我们还需要轴,没有轴的话就没有绘图基准,所以需要添加Axes。也可以理解成为真正可以作画的纸。
1 | fig = plt.figure() |
对于上面的fig.add_subplot(111)就是添加Axes的,
参数的解释:
在画板的第1行第1列的第一个位置生成一个Axes对象来准备作画。也可以通过fig.add_subplot(2, 2, 1)的方式生成Axes,前面两个参数确定了面板的划分,例如 2, 2会将整个面板划分成 2 * 2 的方格
,第三个参数取值范围是 [1, 2*2] 表示第几个Axes。如下面的例子:
绘制操作
在上述所有功能中,您将看到一些常见的参数,如下所示:
- img:您要绘制形状的图像
- color:形状的颜色。对于BGR,将其作为元组传递,例如:(255,0,0)对于蓝色。对于灰度,只需传递标量值即可。
- 厚度:线或圆等的粗细。如果对闭合图形(如圆)传递
-1
,它将填充形状。默认厚度= 1 - lineType:线的类型,是否为8连接线,抗锯齿线等。默认情况下,为8连接线。cv.LINE_AA给出了抗锯齿的线条,看起来非常适合曲线。
绘制直线
1 | cv.line(img,start,end,color,thickness) |
参数:
- img:要绘制直线的图像
- Start,end: 直线的起点和终点
- color: 线条的颜色
- Thickness: 线条宽度
绘制圆形
1 | cv.circle(img,centerpoint, r, color, thickness) |
参数:
- img:要绘制圆形的图像
- Centerpoint, r: 圆心和半径
- color: 线条的颜色
- Thickness: 线条宽度,为-1时生成闭合图案并填充颜色
绘制矩形
1 | cv.rectangle(img,leftupper,rightdown,color,thickness) |
参数:
- img:要绘制矩形的图像
- Leftupper, rightdown: 矩形的左上角和右下角坐标
- color: 线条的颜色
- Thickness: 线条宽度
向图像中添加文字
1 | cv.putText(img,text,station, font, fontsize,color,thickness,cv.LINE_AA) |
参数:
- img: 图像
- text:要写入的文本数据
- station:文本的放置位置
- font:字体
- Fontsize :字体大小
效果展示
我们生成一个全黑的图像,然后在里面绘制图像并添加文字
1 | import numpy as np |
注意:
1 | zeros(): 这是NumPy库中的函数,用于创建指定形状的全零数组。 |
鼠标绘制
1 | import numpy as np |
global 关键字用于声明在函数内部使用全局变量。
逻辑非运算符 not
轨迹栏
在这里,我们将创建一个简单的应用程序,以显示您指定的颜色。您有一个显示颜色的窗口,以及三个用于指定B、G、R颜色的跟踪栏。滑动轨迹栏,并相应地更改窗口颜色。默认情况下,初始颜色将设置为黑色。
对于cv.getTrackbarPos()
函数,第一个参数是轨迹栏名称,第二个参数是它附加到的窗口名称,第三个参数是默认值,第四个参数是最大值,第五个是执行的回调函数每次跟踪栏值更改。回调函数始终具有默认参数,即轨迹栏位置。在我们的例子中,函数什么都不做,所以我们简单地通过。
轨迹栏的另一个重要应用是将其用作按钮或开关。默认情况下,OpenCV不具有按钮功能。因此,您可以使用轨迹栏获得此类功能。在我们的应用程序中,我们创建了一个开关,只有在该开关为ON的情况下,该应用程序才能在其中运行,否则屏幕始终为黑色。
1 | import numpy as np |
img[:]是img的所有元素
获取并修改图像中的像素点
我们可以通过行和列的坐标值获取该像素点的像素值。对于BGR图像,它返回一个蓝,绿,红值的数组。对于灰度图像,仅返回相应的强度值。使用相同的方法对像素值进行修改。
1 | import numpy as np |
获取图像的属性
图像属性包括行数,列数和通道数,图像数据类型,像素数等。
图像通道的拆分与合并
有时需要在B,G,R通道图像上单独工作。在这种情况下,需要将BGR图像分割为单个通道。或者在其他情况下,可能需要将这些单独的通道合并到BGR图像。你可以通过以下方式完成。
1 | # 通道拆分 |
色彩空间的改变
OpenCV中有150多种颜色空间转换方法。最广泛使用的转换方法有两种,BGR↔Gray和BGR↔HSV。
API:
1 | cv.cvtColor(input_image,flag) |
参数:
- input_image: 进行颜色空间转换的图像
- flag: 转换类型
- cv.COLOR_BGR2GRAY : BGR↔Gray
- cv.COLOR_BGR2HSV: BGR→HSV
傅里叶变换
当我们谈论图像处理时,傅里叶变换是一项非常重要的工具。傅里叶变换可以将一个图像从空间域(时域)转换到频域,从而揭示图像中不同频率的成分。在频域中,图像可以表示为由不同频率的正弦和余弦函数组成的复杂图案。
傅里叶变换的基本思想是将一个信号(包括图像)分解为一系列不同频率的正弦和余弦波形
,每个波形都有特定的振幅和相位。这样做的好处是,通过查看图像的频谱,我们可以分析图像中不同频率的成分,并且可以在频域中对图像进行各种操作,例如滤波、增强特定频率的成分等。
频域滤波是在频域中对图像进行滤波操作的过程
。通过对图像的频谱进行操作,我们可以滤除或增强图像中特定频率的成分
。这种方法在图像去噪、边缘检测、图像增强等方面都有广泛的应用。
常见的频域滤波包括:
低通滤波器:滤除高频成分,保留图像中的低频信息,常用于图像去噪。
高通滤波器:滤除低频成分,保留图像中的高频信息,常用于边缘检测。
带通滤波器:只保留某个频率范围内的成分,常用于图像增强和特定频率的提取。
通过在频域中对图像进行滤波操作,我们可以实现一些在空间域中难以实现的图像处理任务,同时也可以更好地理解图像的频率特性.
对于图像,使用2D离散傅里叶变换(DFT)查找频域。一种称为快速傅立叶变换(FFT)的快速算法用于DFT的计算。
numpy实现
傅里叶变换可逆,傅里叶变换是为了得到图片低频和高频做不同的处理。
numpy.fft.fft2:实现傅里叶变换,傅里叶变换返回的是一个复数数组
numpy.fft.fftshiift:将0频域移到频谱中心(低频
20*np.log(np.abs(fshift)):将复数变成灰度图
以上只是得到频谱信息。低频是细节信息,高频是边缘信息。
进行低频或者高频处理之后,进行图像逆变换(即恢复原始图像),处理的信息也会反应在原始图像上。
逆傅里叶变换
numpy实现
numpy.fft.iffshift:fftshiift的逆函数。(中心0频域又回到左上角
numpy.fft.ifft2:逆变换