赞
踩
目录
Python 基于 OpenCV 视觉图像处理实战 之 图像相关的基本概念,以及图像的基础操作 一
Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。
这里使用 Python 基于 OpenCV 进行视觉图像处理,......
像素(Pixel)由 Picture(图像) 和 Element(元素)这两个单词的字母所组成的,是用来计算数码影像的一种单位,如同摄影的相片一样,数码影像也具有连续性的浓淡阶调,我们若把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小方点所组成,这些小方点就是构成影像的最小单位“像素”(Pixel)。
像素是带颜色的,这是因为一个像素就是一个很小的图像单元,单元里面包含很多信息,其中最重要的信息就是颜色。图像颜色的RGB取值范围是0~255,数值的变化代表颜色的深浅变化,值越大表示颜色越浅。对于只有黑白两色的灰度图像,0表示纯黑,255表示纯白。如下图
像素是构成图像的最小单元,像素在一幅图像上规则地排布着。在计算机眼中,图像就像是一个数组,每个数组里面装着一个像素单元。
如下图二维灰度图像像素排列示意图;二维灰度图像是一个二维数组,如图所示,x、y坐标代表了像素的位置,因为通常用f(x,y)表示坐标(x,y)处的像素值。对于灰度图像,f(x,y)的取值范围就是0~255,x的取值范围是从0到图像的高,y的取值范围是从0到图像的宽。
二维彩色图像是怎么构成的呢?
彩色图像的像素包含了RGB的3个值,因此彩色图像就是用3个二维数组表示的,每一个二维数组里面装的就是对应颜色的数值。对于一个BGR构成的图像呢?第1个二维数组里面装的就是坐标(x,y)处B的数值,第2个二维数组里面装的就是坐标(x,y)处G的数值,第3个二维数组里面装的就是坐标(x,y)处R的数值。
在使用图像时,我们经常会看到图像文件有.jpg、.png、.bmp等这样的后缀。这些都是图片的格式,只是不同图片的编解码不同。图片一共有16种格式,一般用得最多的就是前面列出的几种。在OpenCV里面,已经封装了各种图片格式的编解码器,这样用户可以不用关心图片的格式。
一般在存储图片的时候,灰度图片会存储为.bmp格式,彩色图片存储为.jpg格式,带有透明度的图片存储为.png格式。
一个像素的最大值是255,用二进制表示为11111111,在计算机中占8bit的存储空间。
那么什么是位深呢?
位深就是为每个像素分配的比特数。如果比特数是8,每个像素的值可以是0~255。如果是4,每个像素的值是0~15(二进制中为1111)。一般都用255。
前面说灰度图像只需要一个二维数组表示
彩色图像需要3个二维数组表示,如图所示。
这样就引入了图像通道的概念。彩色图像至少包含3个平面:Red、Green和Blue。使用这3种颜色的特定组合可以创建任何颜色。所有的像素都是这3种颜色值的组合。(255,0,0)表示Pure Red;(0,255,0)表示Pure Green;(255,0,255)表示Pure Violate,它的位深为24,因为每个像素为8×3 bit(每个通道8bit)。
彩色图像可以看成3个二维数组,每个二维数组放在一个颜色通道里面。单独拎出一个颜色通道数组显示出来的都是灰度图像,只有3个通道合并才能称之为彩色图像。
因此在图像处理中,经常把颜色通道分离,单独处理一个通道的数组,然后再合并成一幅彩色图像。
src=cv2.imread(filename,flags=1)
参数如下:
·filename:文件的位置,如果只提供文件名,那么文件应该和C++文件在同一目录,否则必须提供图片的全路径。
·flags:表示读取的参数,可以省略,说明原图不做任何修改,如果是0,则表示读取后的是单通道图像。
·函数输出为读取的图像矩阵。
cv2.imshow(winname,mat)
在指定名字的窗口中显示存储在mat中的图像。如果窗口是使用WINDOW_AUTOSIZE创建的,图像会显示为它的原始尺寸,否则图像会调整到窗口尺寸的大小。
参数如下:
·winname:窗口的名字,这个名字是namedWindow()函数创建窗口时使用的。
·mat:存储图像数据的Mat对象。
cv2.imwrite(filename,img)
参数如下:
·filename:const string&类型的filename,写入文件名加上后缀。
·img:ImputArray类型的img,一般填写一个Mat类型的图像数据。
cv2.waitKey(delay=0)
waitKey()函数通过指定delay(毫秒)等待按键的时间。
- 如果delay是0或负数,它会永久等待;
- 如果任意键被按下,该函数就会返回按键的ASCII值,程序继续执行;如果指定的时间没有按下键,该函数返回-1,程序继续执行。
1)编写代码,注意添加图片
2)点击 小三角形运行, Run 'xxxx' 运行
3)运行结果
4)具体代码
- """
- 读取一张图片并显示和存储
- (1)在代码中加入一行import cv2,就完成了OpenCV的包导入。
- (2)调用函数的时候需要在OpenCV原本的函数前加上cv2.,以确保能找到该函数。
- (3)注意Python的缩进方式,它代表了函数的范围。
- (4)imwrite()函数可以将图像保存成不同的格式。
- """
-
- import cv2
-
-
- def main():
- img = cv2.imread("Images/Dog.jpg")
- cv2.imshow("Dog", img)
- cv2.imwrite("Images/save_Dog.jpg", img)
- cv2.waitKey(0)
-
-
- if __name__ == '__main__':
- main()
5)cv2 报错处理
如果提示没有 cv2 模块,可以使用 pip 安装即可
(3.10 python 环境下安装的 pencv-python==4.8.0.74)
命令:pip install opencv-python==4.8.0.74
彩色图像比灰度图像拥有丰富的信息,它的每个像素通常是由红(R)、绿(G)、蓝(B)3个分量来表示的,每个分量介于0~255之间。
图像中呈现的不同的颜色都是由R、G、B这3种颜色混合而成的。在OpenCV里面,彩色图像拥有3个颜色通道,但是通道的顺序是可以变换的,RGB、BRG、BGR、GBR、GRB都有可能。在读取一幅图像的时候,我们对于图像的颜色通道排布并不清楚,因此需要先把图像的颜色通道固定下来,这就需要调用OpenCV的cvtColor()函数。
cvtColor()函数的功能是对图像进行颜色空间变换,原型如下:
dst=cv2.cvtColor(src,code)
参数说明:
·src:输入图像即要进行颜色空间变换的原图像,可以是Mat类。
·code:转换的代码或标识,即在此确定将什么制式的图片转换成什么制式的图片,后面会详细讲述。
注意:
- """
- 读取一张图片保存为灰度图
- (1)在代码中加入一行import cv2,就完成了OpenCV的包导入。
- (2)调用函数的时候需要在OpenCV原本的函数前加上cv2.,以确保能找到该函数。
- (3)注意Python的缩进方式,它代表了函数的范围。
- (4)imwrite()函数可以将图像保存成不同的格式。
- """
-
- import cv2
-
-
- def main():
- # 读取图片
- image = cv2.imread('Images/Dog.jpg')
-
- # 转换为灰度图
- gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
-
- # 保存灰度图
- cv2.imwrite('Images/Gray_Dog.jpg', gray_image)
-
-
- if __name__ == '__main__':
- main()
运行代码,就会保存一张灰度图
在环境中,使用 pip install numpy
1)编写代码测试生一个排列
2)运行结果
3)代码
-
- """
- 使用 numpy 生成一个排列
- """
-
- import numpy as np
-
-
- def main():
- np_arang = np.arange(20).reshape(5, 4)
- print(np_arang)
-
-
- if __name__ == '__main__':
- main()
-
-
1)一些基础的函数
2)ndarray数组的创建
3)数组的维度变换
1、编写代码
2、运行代码
3、运行结果,显示一个灰色图(可能太小),Images 保存一个 Numpy_GrayImg 图片
灰度图像是单通道的,彩色图像拥有R、G、B三个颜色通道。因此在图像处理时,经常把颜色通道分离,单独处理一个通道的数组,然后再合并成一幅彩色图像。
在实际的代码编写中,只需要调用OpenCV中的split()和merge()函数就可以实现图像的通道分离和合并。
A、split()函数的功能是将多通道的矩阵分离成单通道矩阵,原型如下:
[,mv]=cv2.split(src)
参数说明:输入参数为要进行分离的图像矩阵,输出参数为一个Mat数组。
B、merge()函数的功能是将多个单通道图像合成一幅多通道图像,原型如下:
dst=cv2.merge([,dst])
参数说明:输入参数可以是Mat数组,输出为合并后的图像矩阵。
1)编写代码
2)运行代码,结果如下
3)具体代码
- """
- 彩色图像的通道分离和混合
- 1)输入一幅彩色图像,通过程序将其分割成R、G、B这3个通道的图像并显示。
- 2)在分割前需要先确定图像的颜色通道分布,因此先调用cvtColor()函数固定颜色通道
- 3)在图像通道分离后,不同颜色通道的图像显示深浅不一,单通道的图像呈现该颜色通道的灰度信息
- 4)把这3个颜色通道混合一下,这样img3又回到了原来输入的彩色图像样式
- """
-
- import numpy as np
- import cv2
-
-
- def main():
- # 读取图片
- img = cv2.imread("Images/Dog.jpg")
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Dog", img)
-
- # 固定 rgb 通道,分离颜色
- img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
- r, g, b = cv2.split(img2)
-
- cv2.namedWindow("Red", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Red", r)
-
- cv2.namedWindow("Green", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Green", g)
-
- cv2.namedWindow("Blue", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Blue", b)
-
- # 合并颜色通道
- mergeImage = cv2.merge([b, g, r])
-
- cv2.namedWindow("mergeImage", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("mergeImage", mergeImage)
-
- cv2.waitKey(0)
-
-
- if __name__ == '__main__':
- main()
图像的二值化是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。彩色图像二值化最简单的步骤如下:
(1)彩色图像转灰度。
(2)图像阈值化处理,即像素值高于某阈值的像素赋值为255,反之为0。其中,阈值的操作会调用OpenCV的threshold()函数。
threshold()函数声明如下:
ret, dst = cv2.threshold(src, thresh, maxval, type);
函数功能:实现图像固定阈值的二值化。
参数说明:
·src:输入图,只能输入单通道图像,通常来说为灰度图。
·dst:输出图。
·thresh:阈值。
·maxval:当像素值超过了阈值(或者小于阈值,根据type来决定)时所赋予的值。
·type:二值化操作的类型,包含5种类型,即cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV、cv2.THRESH_TRUNC、cv2.THRESH_TOZERO和cv2.THRESH_TOZERO_INV。
1)编写代码
2)运行,得到二值化图像
3)具体代码
- """
- 彩色图像二值化
- 1)高于127的像素全部置为255,低于的全部置为0
- """
-
- import cv2
-
-
- def main():
- # 读取图片,并且灰度处理
- img = cv2.imread("Images/save_Dog.jpg", 0)
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Dog", img)
-
- # 图像二值化
- thresh, dst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("dst", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("dst", dst)
-
- cv2.waitKey(0)
-
-
- if __name__ == '__main__':
- main()
灰度图像的遍历按照访问二维数组的方式得到坐标位置的像素。那对于彩色图像呢?彩色图像可以看出是3维数组,遍历方式如下
- """
- 彩色图像的遍历
- 1)把第一个通道里面的颜色信息全部变为了0
- """
-
- import cv2
-
-
- def main():
- img = cv2.imread("Images/Dog.jpg")
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Dog", img)
-
- # 得到图片的宽高、和维度
- height, width, n = img.shape
- # 拷贝一个图片
- img2 = img.copy()
- for i in range(height):
- for j in range(width):
- # 将第一个通道内的元素重新赋值
- img2[i, j][0] = 0
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("img2", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("img2", img2)
-
- cv2.waitKey(0)
-
-
- if __name__ == '__main__':
- main()
运行,结果如下:
彩色图像转成灰度图像有3种路径:
那么灰度图像有没有可能转换成彩色图像呢?
我们知道灰度图像是单通道的,彩色图像是RGB 3这个颜色通道。
那么是否可以人为地增加图像的通道,伪造出另外两个通道,而另外两个通道可以随机地赋值呢?
1)编写代码
2)运行结果
3)具体代码
- """
- 彩色图像和灰度图像的转换
- 1)主要实现原理:增加图像通道
- 2)新建了一个3通道的空的彩色图像,
- 3)然后将读取的灰度图像放在新建的彩色图像的第一个通道,也就是B通道,
- 4)其他两个通道赋值0,所以图像整体呈现蓝色
- """
-
- import numpy as np
- import cv2
-
-
- def main():
- img = cv2.imread("Images/Dog.jpg")
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Dog", img)
-
- # 获取图片长宽
- height, width, n = img.shape
-
- # 生成一个空的彩色图像
- gray = np.zeros((height, width, 3), np.uint8)
-
- # 遍历像素,0 通道赋值,其余通道 0
- for i in range(height):
- for j in range(width):
- gray[i, j][0] = img[i, j][0]
- gray[i, j][1] = 0
- gray[i, j][2] = 0
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("grayToColor", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("grayToColor", gray)
-
- cv2.waitKey(0)
-
-
- if __name__ == '__main__':
- main()
4)上述方法转换的图像颜色很单一。有没有更加智能的方法呢?在摄像技术不是很成熟的时期,人们给拍摄出来的黑白照片上色,发明了一种伪彩色图像技术。在OpenCV里面,可以用预定义好的Colormap(色度图)来给图片上色,效果如下
代码如下:
- """
- 彩色图像和灰度图像的转换
- 1)用预定义好的Colormap(色度图)来给图片上色
- 2)伪彩色图像目前主要应用在对高度、压力、密度、湿度等描述上,彩色数据可视化。
- """
-
- import numpy as np
- import cv2
-
-
- def main():
- img = cv2.imread('Images/Gray_Dog.jpg')
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("Dog", img)
-
- # 色度图上色
- img_Color = cv2.applyColorMap(img, cv2.COLORMAP_JET)
-
- # 设置窗口属性,并显示图片
- cv2.namedWindow("img_Color", cv2.WINDOW_KEEPRATIO)
- cv2.imshow("img_Color", img_Color)
-
- cv2.waitKey(0)
-
-
- if __name__ == '__main__':
- main()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。