赞
踩
OpenCV中使用数组表示图像数据,不过这里的数组并不是Python数组,而是NumPy数组。NumPy是非常著名的科学计算库,可用于进行各种科学计算,由于底层使用C语言实现,所以效率非常高。
读者使用type函数输出imread函数的返回值看看这个函数返回的到底是什么数据类型,代码如下:
- rgb_image = cv2.imread("flower.png")
- print(type(rgb_image))
运行程序,会输出如下的内容:
<class 'numpy.ndarray'>
很明显,imread函数返回的是一个Numpy数组。既然OpenCV内部使用了NumPy数组管理图像,那么也可以通过创建NumPy数组的方式来创建图像,所以本节将直接通过NumPy来操作黑白和彩色图像。
在OpenCV中,黑白图像通过一个二维数组表示,彩色图像使用一个三维数组表示,这也非常容易理解。对于黑白图像来说,每一个像素点只有2个颜色:黑和白。通常用255表示白,用0表示黑。二维数组的每一个数组值正好表示黑和白两个颜色,数组的行和列就是图像的高和宽(图像尺寸),数组元素的个数就是图像中像素的个数。
对于彩色图像(RGB色彩空间)来说,每一个像素点需要3个值表示3种颜色(R、G和B),所以需要多出一个维度来表示颜色,因此,彩色图像需要用3维数组表示。
在黑白图像中,像素值为0表示纯黑色,像素值为255表示纯白色。所以只需要用NumPy创建一个二维数组,并且每一个数组值为0,就是纯黑色图像,每一个数组值为255,就是纯白色图像。
下面的代码创建一个宽度和高度都是200的NumPy数组,数组元素格式为无符号8位整数,用0填充整个数组,最后将数组作为图像显示。
- import cv2
- import numpy as np
-
- width = 200 # 图像的宽
- height = 200 # 图像的高
- # 创建指定宽高、单通道、像素值都为0的图像
- img = np.zeros((height, width), np.uint8)
- cv2.imshow("black image", img) # 显示纯黑图像
- cv2.waitKey()
- cv2.destroyAllWindows()
运行程序,会看到如图1所示的纯黑图像。
创建纯白图像需要将二维数组中的每一个值都设置为255,可以先创建纯黑图像,然后将图像中所有的像素值都改为255,或者直接使用NumPy提供的ones函数创建一个像素值为1的数组,然后让数组乘以255,同样可以得到一个数组值都为255的数组,也就是纯白色的图像。
下面的代码创建一个宽度和高度都是200的NumPy数组,数组元素格式为无符号8位整数,用1填充整个数组,然后让数组与255相乘,最后将数组作为图像显示。
- import cv2
- import numpy as np
-
- width = 200 # 图像的宽
- height = 200 # 图像的高
- # 创建指定宽高、单通道、像素值都为1的图像
- img = np.ones((height, width), np.uint8) * 255
- cv2.imshow("white", img) # 显示图像
- cv2.waitKey()
- cv2.destroyAllWindows()
运行程序,会看到如图2所示的纯白图像。
下面的代码先绘制黑色图像作为背景,然后用切片索引的方式将图像中纵坐标在80~150之间,横坐标在60~130之间的矩形区域改为白色,代码如下:
- import cv2
- import numpy as np
-
- width = 200
- height = 200
- # 创建指定宽高、单通道、像素值都为0的图像
- img = np.zeros((height, width), np.uint8)
- # 图像纵坐标80~150、横坐标60~130之间的区域变为白色
- img[80:151, 60:131] = 255
- cv2.imshow("img", img) # 显示图像
- cv2.waitKey()
- cv2.destroyAllWindows()
运行程序,会看到如图3所示的效果。
注意:Python切片是半开半闭区间,即取值范围并不包含冒号(:)后面数值。例如,纵坐标在80~150范围内,应该使用[80:151]。
下面的代码在黑色背景正中心绘制3个不同半径的同心圆,半径分别为30,50和80。并且让同心圆的圆周线厚度为3。
通过像素点绘制圆形最常用的方式是通过三角函数计算圆周线上每一个像素点的坐标,然后在这些坐标上绘制白色像素点。如果加厚圆周线,只需要再绘制相邻半径的同心圆即可。例如,让半径为30的圆的圆周线的厚度是3,只需要在绘制半径分别为29和31的同心圆即可,代码如下:
- import cv2
- import math
- import numpy as np
-
- width = 200
- height = 200
- # 创建指定宽高、单通道、像素值都为0的图像
- img = np.zeros((height, width), np.uint8)
- # 同心圆中心坐标
- centerX = 100
- centerY = 100
- # 定义同心圆半径
- radiusList = [29,30,31, 49,50,51, 79,80,81]
- # 通过循环,计算同心圆的圆周线上的坐标,并将坐标对应的位置设置为255(白色)
- for radius in radiusList:
- # 从0到359度
- for angle in range(0,360):
- # 将角度转换为弧度
- radian = (angle/360) * 2 * math.pi
- # 计算圆周线当前点的横坐标
- pointX = int(centerX + radius * math.cos(radian))
- # 计算圆周线当前点的纵坐标
- pointY = int(centerY - radius * math.sin(radian))
- #将圆周线上的像素点设置为白色
- img[pointY, pointX] = 255
- cv2.imshow("img", img) # 显示图像
- cv2.waitKey()
- cv2.destroyAllWindows()
运行程序,会看到如图4所示的效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。