【数字图像处理学习笔记】一、安装,读取、展示、存储图像 接上边链接的内容:
4、窗口销毁函数
两个常用的窗口销毁函数 ① 定义:cv2.destroyWindow(windows_name) #销毁单个特定窗口 ②cv2.destroyAllWindows() #销毁全部窗口,无参数 举个例子:
import cv2 as cv
readPicture = cv.imread('img/destination.jpg', 1)
cv.imshow("picture", readPicture)
cv.imshow("aaa", readPicture)
if cv.waitKey(0) == 27:
cv.destroyWindow("picture")
注:理应按0停止掉picture窗口,但是我这里是按了ESC全部关闭了,这里留一个疑问,因为这一步相当于destroyAllWindows()的功能了。 对于destroyAllWindows()函数来说,实验例子只需要将上边的例子中最后一句改成cv.destroyAllWindows()就可以了。
*还要提到的是cv2的waitKey函数 定义:cv2.waitKey(time_of_milliseconds) 针对于time_of_milliseconds>0,举个例子:
import cv2 as cv
readPicture = cv.imread('img/destination.jpg', 1)
cv.imshow("picture", readPicture)
cv.imshow("aaa", readPicture)
if cv.waitKey(3000):
cv.destroyAllWindows()
在3s后,所有的窗口会自动关闭。
等待按键的方式前面其实已经用过了,如下:
if cv.waitKey(0) == 27:
cv.destroyWindow('picture')
又或者
if cv.waitKey(0) == ord('A'):
cv.destroyWindow('picture')
解释一下ord()函数,ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
三、图像色彩空间变换函数cv2.cvtColor
定义:cv2.cvtColor(input_image, flag) 如果想查看参数flag的全部类型,执行以下程序查阅,总共有274种空间转换类型:
import cv2
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)
举个例子使用一下这个函数
import cv2 as cv
rgb_img = cv.imread("img/testImg.jpg", 1)
gray_img = cv.cvtColor(rgb_img, cv.COLOR_BGR2GRAY)
cv.imshow("gray_img", gray_img)
if cv.waitKey(0) == 27:
cv.destroyAllWindows()
结果如下: 这里引用一段看别人的笔记看到的话: 在之后的图像特征提取和识别学习中,我们经常使用的是将彩色图像转化成灰度图像, 这里解释一下为什么我总是对灰度图进行处理,增强对以后图像处理操作的理解 图像的颜色主要是由于图像受到外界光照影响随之产生的不同颜色信息,同一个背景物的图像在不同光源照射下产生的不同颜色效果的图像,因此在我们做图像特征提取和识别过程时,我们要的是图像的梯度信息,也就是图像的本质内容,而颜色信息会对我们对梯度信息提取造成一定的干扰,因此我们会在做图像特征提取和识别前将图像转化为灰度图,这样同时也降低了处理的数据量并且增强了处理效果。
四、绘制自定义数字图像
1、一些基础知识
对于一个长宽分别为w、h的RGB彩色图像来说,它的每个像素值是由(B、G、R)的一个tuple组成,opencv-python中每个像素三个值的顺序是B、G、R,而对于灰度图像来说,每个像素对应的便只是一个整数,如果要把像素缩放到0、1,则灰度图像就是二值图像,0便是黑色,1便是白色。通过下面的例子来理解一下
import cv2 as cv
rgb_img = cv.imread("img/testImg.jpg", 1);
print(rgb_img.shape)
print(rgb_img[0, 0])
print(rgb_img[0, 0, 0])
gray_img = cv.cvtColor(rgb_img, cv.COLOR_BGR2GRAY)
print(gray_img.shape)
print(gray_img[0, 0])
上边程序运行结果如下: (333, 500, 3) [224 179 109] 224 (333, 500) 163
从运行结果可以看出: ①彩色图像高度height=333,宽度width=500,通道数为3(由第一条结果 (333,500,3)看出来 ) ②像素(0,0)的值是(224,179,109),即B=224,G=179,R=109。对灰度图像来说是单通道的 (0,0,0)代表的是一个黑色像素,而(255,255,255)便代表一个白色像素。如此,当B=0,G=0,R=0相当于关闭了颜色通道,也就相当于无光照进入,所以整个图像是黑的,而(255,255,255)相当于打开了B、G、R所有通道光线全部进入,因此便是白色的 明白了这个道理,我们便可以来绘制任意的彩色图像和灰色图像了
*开始之前,说明一个函数:numpy库中的ones函数,这个函数返回给定形状和类型的数组,填充1 定义:numpy.ones(shape,[dctype],[order]) 写两个例子试试: 例子一:
import numpy as np
white_img = np.ones((3, 3, 2))
print(white_img)
结果如下: [ [ [1. 1.] [1. 1.] [1. 1.] ] [ [1. 1.] [1. 1.] [1. 1.] ] [ [1. 1.] [1. 1.] [1. 1.] ] ] 生成了一个三行,三列,每个里边包含两个元素的数组,这段代码dctype为默认值float64
再来一个例子:
import numpy as np
white_img = np.ones((3, 3, 3),dctype=int)
print(white_img)
结果如下: [ [ [1 1 1] [1 1 1] [1 1 1] ] [ [1 1 1] [1 1 1] [1 1 1] ] [ [1 1 1] [1 1 1] [1 1 1] ] ] 只是每一个里边变成了3个元素,因为我们给dctype设置值为int,所以这里展示的元素和上面略有不同。 还需要说明一下NumPy数据类型,这个直接看菜鸟教程的表就能明白了 接下来我们开始绘制一个白色的图,先来看看这段代码:
import numpy as np
white_img = np.ones((3, 3, 3), np.uint8)
white_img = 255 * white_img
print(white_img)
接下来给出一些解释: 第二行中,np.unit8不过就是numpy的一个数据类型——无符号整数(0 to 255),不需要看复杂了。 根据前面提到的numpy.ones()函数,我们可以知道,这就是生成了一个三行,三列,每个数组里边包含了三个元素,故可以知道,执行完第二步得到的结果应该是这样的: [ [ [1 1 1] [1 1 1] [1 1 1] ] [ [1 1 1] [1 1 1] [1 1 1] ] [ [1 1 1] [1 1 1] [1 1 1] ] ] 那第三行是什么意思呢?其实就是线性代数中数与矩阵相乘
不难理解,其实就是把255乘到矩阵里去,故我们可以得到打印的结果: [ [ [255 255 255] [255 255 255] [255 255 255] ] [ [255 255 255] [255 255 255] [255 255 255] ] [ [255 255 255] [255 255 255] [255 255 255] ] ] 接下来,将数组的行数列数扩大一些,比如扩大至500。而前面又可以知道,[255 255 255]无非就是一个像素点,不记得的话可以看一下本例开始的例子和下面的阐述。 前面我们又提过[255 255 255]就是一个白像素点,所以,我们可以将这个矩阵展示成一个图,完整代码如下:
import cv2 as cv
import numpy as np
white_img = np.ones((500, 500, 3), np.uint8)
white_img = 255 * white_img
cv.imshow("white_img", white_img)
if cv.waitKey(0) == 27:
cv.destroyAllWindows()
结果如下: 如果将255换成150,即是黑和白之间的一种灰色,如下
2、绘制简单图像
先来熟悉一下opencv中一些简单几何图像基本绘制函数,然后我们尝试着在上面白色的图像上进行添加新的图像物体,接下来介绍直线cv2.line、长方形cv2.rectangle、圆cv2.circle、椭圆cv2.ellipse、多边形cv2.polylines等集合图像绘制函数。
(1)cv2.line函数
定义:cv2.line(image, starting, ending, color, thickness, lineType)
联合上边的代码,写一行代码测试一下:
import cv2 as cv
import numpy as np
white_img = np.ones((500, 500, 3), np.uint8)
white_img = 255 * white_img
cv.line(white_img, (60, 60), (150, 150), (255, 191, 0), 3)
cv.imshow("white_img", white_img)
if cv.waitKey(0) == 27:
cv.destroyAllWindows()
(2)cv2.rectangle函数
<mark>定义:cv2.rectangle(image, top-left, bottom-right, color, thickness, lineType)</mark>
因为参数与(1)中基本一样,所以只介绍其中不一样的两个参数 此处省略完整代码,只需在(1)代码中cv.line(…)部分下加上:(此处顺便测试一下thickness函数=-1情况)
cv.rectangle(white_img, (160, 160), (250, 250), (87, 139, 46), -1)
结果如下:
(3)cv2.circle函数
<mark>定义:cv2.circle(image, center, radius, color, thickness, lineType)</mark>
测试代码如下:
cv.circle(white_img, (300, 300), 40,(238, 104, 123), 2)
(4)cv2.ellipse函数
定义:cv2.circle(image, center, (major-axis-length, minor-axis-length), angle, startAngle, endAngle, color, thickness, lineType) 测试代码如下:
cv.ellipse(white_img, (80, 320), (100, 50), 0, 0, 360, (127, 255, 0), 4)
(5)cv2.polylines函数
定义:cv2.polylines(image, [point-set], flag, color, thickness, lineType) 测试代码如下:
pts = np.array([[20, 30], [25, 31], [67, 32], [53, 24]], np.int32)
cv.polylines(white_img, [pts], True, (0, 0, 0), 2)
结果如下: 贴一段完整代码:
import cv2 as cv
import numpy as np
white_img = np.ones((500, 500, 3), np.uint8)
white_img = 255 * white_img
cv.line(white_img, (60, 60), (150, 150), (255, 191, 0), 3)
cv.rectangle(white_img, (160, 160), (250, 250), (87, 139, 46), -1)
cv.circle(white_img, (300, 300), 40,(238, 104, 123), 2)
cv.ellipse(white_img, (80, 320), (100, 50), 0, 0, 360, (127, 255, 0), 4)
pts = np.array([[20, 30], [25, 31], [67, 32], [53, 24]], np.int32)
cv.polylines(white_img, [pts], True, (0, 0, 0), 2)
cv.imshow("white_img", white_img)
if cv.waitKey(0) == 27:
cv.destroyAllWindows()
|