【OpenCV入门】第一部分——图像处理基础

本文结构

图像处理的基本操作

图像处理包括4个基本操作:读取图像显示图像保存图像获取图像属性

读取图像

imread()

python 复制代码
image = cv2.imread(filename,flags)
  • filename:目标图像的完整路径名。
  • flags :图像的颜色类型的标记,有0和1两个值,其中1为默认值。当读取一幅彩色图像时,如果想要得到一幅彩色图像 ,那么flags的值为1(此时flags的值可以省略);想要得到一幅灰度图像则为0。
  • image:是imread()方法的返回值,返回的是读取到的彩色图像或者灰度图像。

其实就是读取了一个存在filename路径的图片,然后用image去表示这个图片而已(image只是一个举例,你爱叫啥叫啥),flags是0还是1取决于你想要彩图还是灰白图。

实例1: 读取当前项目目录下的图像

在PyCharm中的Demos项目下,有一幅名为1.jpg的图像。

现在先使用imread()方法读取1.jpg,再使用print()方法打印1.jpg。代码如下所示:

python 复制代码
import cv2 # 导入库

image = cv2.imread("1.jpg",1) # 读取1.jpg,等价于image = cv2.imread("1.jpg")
print(image) # 打印1.jpg

部分结果如下:
图中输出的数字是1.jpg的部分像素值。

如果图像存储在电脑C盘中,示例代码如下:

python 复制代码
import cv2 #opencv读取的格式是BGR

img = cv2.imread('C:/Users/lenovo/Pictures/Saved Pictures/castle.jpg') # 路径中不能出现中文
print(image)

注意:"D:/1.jpg"等价于"D:\1.jpg"

显示图像

imshow()

imshow()方法用于显示图像:

python 复制代码
cv2.imshow(winname,mat)
  • winname: 显示图像的窗口名称。
  • mat: 要显示的图像

waitKey()

waitKey()方法用于等待用户按下键盘上的某个按键时将执行waitKey()方法,并且获取与这个按键相对应的ASCII码:

python 复制代码
retval = cv2.waitKey(delay)
  • delay:等待用户按下键盘上按键的时间,单位为毫秒(ms)。当delay的值为负数,0或者空时,表示无限等待用户按下键盘上按键的时间。
  • retval:与被按下的按键相对应的ASCII码。例如ESC键的ASCII码是27,当用户按下该键时,waitKey()方法的返回值为27.如果没有按键被按下,waitKey()方法的返回值是-1。

destroyAllWindows()

destroyAllWindows()方法用于销毁所有正在显示图像的窗口:

python 复制代码
cv2.destroyAllWindows()

实例2: 窗口显示图像

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("image",image)       # 在名为 image 的窗口中显示1.jpg
cv2.waitKey()                   # 按下任何键盘按键中
cv2.destroyAllWindows()         # 销毁所有窗口

结果如下:

如果想设置窗口显示图像的时间为5s,示例代码如下:

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("image",image)       # 在名为 image 的窗口中显示1.jpg
cv2.waitKey(5000)               # 括号内单位为ms
cv2.destroyAllWindows()         # 销毁所有窗口

注意:

  • 显示图像的窗口名称不能是中文,否则会乱码。
  • 为了能够正常显示图像,要在cv2.imshow()后紧跟着cv2.waitKey()。

保存图像

imwrite()

imwrite()可按照指定路径保存图像

python 复制代码
cv2.imwrite(filename,img)
  • filename: 保存图像时所用的完整路径
  • img: 要保存的图像

实例3: 保存图像

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imwrite("D:/Pictures/1.jpg",image) # 把1.jpg保存为D盘根目录下,Pictures文件夹中的1.jpg

注意: 运行上述代码前,要在E盘根目录下新建一个空的Pictures文件夹

复制图像

copy()

在OpenCV中,图像是由二维数组或者三维数组表示的。因此,使用copy()方法除了能够复制数组外,还能够复制图像。

实例4:复制图像

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
copyImage = image.copy()
cv2.imshow("img",image)
cv2.imshow("copyImage",copyImage)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:

获取图像属性

处理图像的过程中,经常需要获取图像的大小、类型等图像属性。为此,OpenCV提供了shape、size和dtype这3个常用属性。

  • shape: 如果是彩色图像,那么获取的是一个包含图像的像素行数、像素列数、通道数的数组,数组的格式为(像素行数,像素列数,通道数);如果是灰度图像,那么获取的是一个包含图像的像素列数、像素行数的数组,数组的格式为(像素行数,像素列数)
  • size: 获取的是图像包含的像素总数,其值为像素行数×像素列数×通道数(灰度图像的通道数为1)
  • dtype: 获取的是图像的数据类型

实例4: 打印彩色图像和灰度图像的属性

python 复制代码
import cv2

image_Color = cv2.imread("1.jpg", 1)  # 读取1.jpg
print("获取彩色图像的属性:")
print("shape =",image_Color.shape) #打印彩色图像的(像素行数,像素列数,通道数)
print("size =",image_Color.size) #打印彩色图像包含的像素总数
print("dtype =",image_Color.dtype) #打印彩色图像的数据类型

image_Gray = cv2.imread("1.jpg", 0)  # 读取1.jpg的灰度图像
print("获取灰度图像的属性:")
print("shape =",image_Gray.shape) #打印灰度图像的(像素行数,像素列数)
print("size =",image_Gray.size) #打印灰度图像包含的像素总数
print("dtype =",image_Gray.dtype) #打印灰度图像的数据类型

结果如下:

像素

像素是构成数字图像的基本单位。将电脑上的一幅图片放大,会发现图像是由许多个小方块组成的,通常把一个小方块称作一个像素。因此,一个像素是具有一定面积的一个块,而不是一个点。需要注意的是,像素的形状是不固定的,大多数情况下,像素被认为是方形的,但有时也可能是圆形的或者是其他形状的。

确定像素的位置

在OpenCV中,正确表示图像中某个像素坐标的格式为 (y,x) ,方向示意图如下:

实例5: 表示图中的指定像素

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
px = image[50,30] # 坐标(50,30)上的像素

获取像素的BGR值

人眼能够感知红色、绿色和蓝色这3种不同的颜色,称为三基色。计算机利用色彩空间对颜色进行编码,把与"三基色"对应的色彩空间称作"RGB色彩空间"。

在RGB色彩空间种包含3个通道:R通道、G通道、B通道,分别代表红色通道、绿色通道、蓝色通道,每个通道都在区间[0,255]内进行取值。这样,计算机通过为这3个色彩通道取不同的值来表示不同的颜色。

OpenCV默认的通道顺序是B->G->R。也就是说,当OpenCV获取图像内某个像素的值时,这个值指的是这个像素的BGR值,OpenCV默认使用的色彩空间是BGR色彩空间。

在实例5中,凭借一个标签px就成功地表示了坐标(50,30)上的像素。如果使用print()方法打印这个像素,就会得到这个像素的BGR值。

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
px = image[50,30] # 坐标(50,30)上的像素,同时获取三个通道的值
blue = image[50, 30, 0]  # 坐标(50,30)上的像素的B通道的值
green = image[50, 30, 1]  # 坐标(50,30)上的像素的G通道的值
red = image[50, 30, 2]  # 坐标(50,30)上的像素的R通道的值
print(px)
print(blue,green,red)

结果如下:

修改像素的BGR值

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
px = image[50, 30]  # 坐标(50,30)上的像素
print("像素的初试BGR值是:",px)
px = [255,255,255] # 把坐标上的像素的值修改为[255,255,255]
print("像素修改后的BGR值是:",px)

结果如下:

当图像中的每个像素的B、G、R这3个数值相等时,就可以得到灰度图像。其中,当B = G = R = 0 时,像素呈现纯黑色 ;当B = G = R = 255 时,像素呈现纯白色

实例6: 修改图像中的指定区域内的所有像素

在图像上设定4个点,将4个点围成的区域内的所有像素都修改为白色。

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
for i in range(241, 292):  # i表示横坐标,在区间[241,291]内取值
    for j in range(168, 219):  # j表示纵坐标,在区间[168,218]内取值
        image[i, j] = [255, 255, 255]  # 把区域内的所有像素都修改为白色
cv2.imshow("img_02", image)  # 显示像素被修改后的图像
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:

色彩空间

上文中简单介绍了RGB色彩空间和BGR色彩空间。接下来将介绍在OpenCV中另外两个比较常见的色彩空间:GRAY色彩空间和HSV色彩空间。

GRAY色彩空间

GRAY色彩空间通常指的是灰度图像。灰度图像是一种每个像素都是从黑到白,被处理为256个灰度级别的单色图像。这256个灰度级别分别用区间[0,255]中的数值表示。"0"表示黑色,"255"表示白色,0~255之间的数值表示不同亮度(即色彩的深浅程度)的深灰色和浅灰色。

cvtColor()------从BGR色彩空间转换到GRAY色彩空间

OpenCV可以使用imread()方法把图片读取为灰度图像。除此之外,OpenCV还提供了cvtColor()方法用于转换图像的色彩空间。

python 复制代码
dst = cv2.cvtColor(src,code)
  • src: 转换色彩空间前的初始图象
  • code: 色彩空间转换码
  • dst: 转换色彩空间后的图像

当一幅彩色图像从BGR色彩空间转换到GRAY色彩空间时,需要使用的色彩空间转换码时cv2.COLOR_BGR2GRAY。

实例7: 从BGR色彩空间转换到GRAY色彩空间

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
# 将1.jpg从BGR色彩空间转换到GRAY色彩空间
gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow("GRAY", gray_image)  # 显示灰度图像
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下;

虽然色彩空间类型转换是双向的,而且OpenCV也提供了cv2.COLOR_GRAY2BGR这个色彩空间转换码,但是灰度图像是无法转换成彩色图像的。这是因为在彩色图像转换成灰度图像的过程中,已经丢失了颜色比例。

HSV色彩空间

RGB色彩空间是基于三基色而言的,即红色、绿色和蓝色。而HSV色彩空间则是基于色调、饱和度和亮度而言的。

  • 色调(H)是指光的颜色。OpenCV中,色调在区间[0,180]内取值。例如代表红色、黄色、绿色和蓝色的色调值分别为0、30、60和120。
  • 饱和度(S)是指色彩的深浅。在OpenCV中,饱和度在[0,255]内取值。当饱和度为0时,图像将变为灰度图像。
  • 亮度(V)是指光的明暗。与饱和度相同,在OpenCV中,亮度在区间[0,255]内取值。亮度值越大,图像越亮;当亮度值为0时,图像呈纯黑色。

从BGR色彩空间转换到HSV色彩空间

当一幅彩色图像从BGR色彩空间转换到HSV色彩空间时,需要使用的色彩空间转换码是cv2.COLOR_BGR2HSV

实例8: 从BGR色彩空间转换到HSV色彩空间

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
# 将1.jpg从BGR色彩空间转换到HSV色彩空间
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
cv2.imshow("HSV", hsv_image)  # 显示灰度图像
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:

通道

在BGR色彩空间中,包含3个通道:B通道、G通道和R通道。

拆分通道

为了拆分一幅图像中的通道,OpenCV提供了split()方法。

拆分一幅BGR图像中的通道

python 复制代码
b, g, r = cv2.split(bgr_image)
  • bgr_image: 一幅BGR图像
  • b: B通道图像
  • g: G通道图像
  • r: R通道图像

实例9: 拆分一幅BGR图像中的通道

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
b,g,r=cv2.split(image)
cv2.imshow("B",b)
cv2.imshow("G",g)
cv2.imshow("R",r)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:

可以看到结果是0三个不同亮度的灰度图像。这是因为当程序执行到cv2.imshow("B",b)时原图像B、G、R这3个通道的值都会被修改为B通道的值,即(B,B,B),其余同理。对于BGR图像,只要B=G=R(即数值相等),就可以得到灰度图像。

拆分一幅HSV图像中的通道

python 复制代码
h, s, v = cv2.split(hsv_image)
  • hsv_image: 一幅HSV图像。
  • h: H通道图像
  • s: S通道图像
  • v: V通道图像

实例10: 拆分一幅HSV图像中的通道

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv_image)
cv2.imshow("H",h)
cv2.imshow("S",s)
cv2.imshow("V",v)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:

合并通道

使用merge()方法合并H、S、V通道图像。

python 复制代码
hsv = cv2.merge([h, s, v])
  • h: H通道图像
  • s: S通道图像
  • v: V通道图像
  • hsv:合并H通道图像、S通道图像和V通道图像后得到的图像

实例11: 合并H、S、V通道图像

首先将图像从BGR色彩空间转换到HSV色彩空间,然后拆分得到HSV图像中的通道,接着合并拆分后的通道图像,最后显示合并通道的HSV图像。

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv_image)
hsv = cv2.merge([h,s,v])
cv2.imshow("HSV",hsv)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:

综合运用拆分通道和合并通道

在HSV色彩空间中,如果保持其中两个通道的值不变,调整第3个通道的值,会得到响应的艺术效果。

实例12: 只把H通道的值调整为180

首先将图像从BGR色彩空间转换到HSV色彩空间;然后拆分得到HSV图像中的通道;接着让S通道和V通道的值表示不变,把H通道的值调整为180;再接着合并拆分后的通道图像,把这个图像从HSV色彩空间转换到BGR色彩空间;最后显示得到的BGR图像。

python 复制代码
import cv2

image = cv2.imread("1.jpg", 1)  # 读取1.jpg
cv2.imshow("img_01", image)  # 显示图像
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV) # 将图像从BGR色彩空间转换到HSV色彩空间
h,s,v=cv2.split(hsv_image) # 拆分得到HSV图像中的通道
h[:,:] = 180 # 让S通道和V通道的值表示不变,把H通道的值调整为180
hsv = cv2.merge([h,s,v]) # 合并拆分后的通道图像
new_Image = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR) # 把这个图像从HSV色彩空间转换到BGR色彩空间
cv2.imshow("NEW",new_Image)
cv2.waitKey()
cv2.destroyAllWindows()  # 关闭所有的窗口时,销毁所有窗口

结果如下:

alpha通道

OpenCV在B、G、R三个通道的基础上,又增加了一个A通道,即alpha通道,用于设置图像的透明度。在BGRA色彩空间中,alpha通道在区间[0,255]内取值,其中0表示透明,255表示不透明。

实例13: 调整A通道的值

python 复制代码
import cv2

bgr_image = cv2.imread("1.jpg", 1)  # 读取1.jpg
bgra_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2BGRA)  # 把图片从BGR色彩空间转换到BGRA色彩空间
b, g, r, a = cv2.split(bgra_image)  # 拆分BGRA图像中的通道
a[:, :] = 172  # 将BGRA图像的透明度调整为172(半透明)
bgra_172 = cv2.merge([b, g, r, a])  # 合并拆分后并将透明度调整为172的通道图像
a[:, :] = 0  # 将BGRA图像的透明度调整为0(透明)
bgra_0 = cv2.merge([b, g, r, a])  # 合并拆分后并将透明度调整为0的通道图像
cv2.imwrite("D:/bgra_image.png", bgra_image)  # 在D盘根目录下,保存BGRA图像
cv2.imwrite("D:/bgra_172.png", bgra_172)  # 在D盘根目录下,保存透明度为172的BGRA图像
cv2.imwrite("D:/bgra_0.png", bgra_0)  # 在D盘根目录下,保存透明度为0的BGRA图像

如果使用imshow()方法的话,窗口里显示的图像是相同的。为了显示这3幅图像的不同效果,需要使用imwrite()方法来保存。

相关推荐
这个男人是小帅21 分钟前
【GAT】 代码详解 (1) 运行方法【pytorch】可运行版本
人工智能·pytorch·python·深度学习·分类
__基本操作__23 分钟前
边缘提取函数 [OPENCV--2]
人工智能·opencv·计算机视觉
这是一个图像26 分钟前
从opencv-python入门opencv--图像处理之图像滤波
图像处理·opencv·计算机视觉·中值滤波·高斯滤波·双边滤波·图像滤波
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
Shy9604184 小时前
Doc2Vec句子向量
python·语言模型
秀儿还能再秀7 小时前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
阿_旭8 小时前
如何使用OpenCV和Python进行相机校准
python·opencv·相机校准·畸变校准
幸运的星竹8 小时前
使用pytest+openpyxl做接口自动化遇到的问题
python·自动化·pytest
kali-Myon9 小时前
ctfshow-web入门-SSTI(web361-web368)上
前端·python·学习·安全·web安全·web