赞
踩
在本节的内容中,首先学习读取图像、显示图像以及保存图像的知识,然后讲解绘图、图像算法和几何变换的知识。
1. 读取图像
在OpenCV-Python中,使用内置函数cv.imread()读取图像,被读取的图像应该在工作目录中,或使用图像的完整路径。函数cv.imread()的语法格式如下:
cv2.imread(filepath,flags)
(1)filepath:表示要读入图片的完整路径
(2)flags:读入图片的标志,用于设置读取图像的方式,主要方式有:
2. 显示图像
在OpenCV-Python中,使用内置函数cv.imshow()在窗口中显示图像,窗口会自动适合图像的尺寸大小。函数cv.imshow()的语法格式如下:
cv.imshow(winname, mat)
在下面的实例文件cv01.py中,演示了使用OpenCV-Python读取并显示指定图像的过程。
实例3-1:读取并显示指定的图像
源码路径:daima\3\cv01.py
- import cv2 as cv
- print( cv.__version__ )
- #加载彩色灰度图像
- img = cv.imread('111.jpg',0)
- cv.imshow('image',img)
- cv.waitKey(0)
- cv.destroyAllWindows()
执行效果如图3-1所示。
图3-1 执行效果
注意:在特殊情况下,可以创建一个空窗口,然后再将图像加载到该窗口。在这种情况下,可以指定窗口是否可调整大小,这是通过功能函数cv.namedWindow()实现的。在默认情况下,该标志为cv.WINDOW_AUTOSIZE。但是,如果将标志指定为cv.WINDOW_NORMAL,则可以调整窗口大小。当图像尺寸过大以及向窗口添加跟踪栏时,这将很有帮助。例如下面的代码:
- cv.namedWindow('image',cv.WINDOW_NORMAL)
- cv.imshow('image',img)
- cv.waitKey(0)
- cv.destroyAllWindows()
在OpenCV-Python中,使用内置函数cv.imwrite()保存图像。例如:
cv.imwrite('messigray.png',img)
其中第一个参数表示需要保存图像的文件名,要保存图片为哪种格式,就带什么后缀。第二个参数表示保存的图像,功能是将图像以PNG格式保存在工作目录中。
例如在下面的实例中,先准备一幅彩色图像文件111.jpg。然后以灰度模式加载并显示图像文件111.jpg,按下S键后将灰度文件保存为new.png并退出,或者按ESC键直接退出而不保存。
实例3-2:以灰度模式加载、显示、保存图像
源码路径:daima\3\cv02py
- import cv2 as cv
- img = cv.imread('111.jpg',0)
- cv.imshow('image',img)
- k = cv.waitKey(0)
- if k == 27: # 等待ESC退出
- cv.destroyAllWindows()
- elif k == ord('s'): # 等待关键字,保存和退出
- cv.imwrite('new.png',img)
- cv.destroyAllWindows()
执行效果如图3-2所示。
图3-2 执行效果
在Python程序中,经常使用Matplotlib实现绘图功能,例如数据可视化中的统计图。在使用OpenCV-Python显示图像时,可以借助于Matplotlib缩放图像货保存图像。例如在下面的实例中,在Matplotlib中使用OpenCV-Python显示了一幅指定的图像。
实例3-3:在Matplotlib中使用OpenCV-Python显示了一幅指定的图像
源码路径:daima\3\cv03.py
- import cv2 as cv
- from matplotlib import pyplot as plt
- img = cv.imread('111.jpg',0)
- plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
- plt.xticks([]), plt.yticks([]) # 隐藏 x 轴和 y 轴上的刻度值
- plt.show()
执行效果如图3-3所示。
图3-3 执行效果
在OpenCV-Python绘图应用中,经常用到的内置函数有cv.line()、cv.circle()、cv.rectangle()、cv.ellipse()和cv.putText()等,这些函数的的常用参数有:
(1)画直线
在OpenCV-Python中使用内置函数cv.line()绘制一条线,在绘制时需要设置开始坐标和结束坐标。例如在下面的实例中,演示了在OpenCV-Python中绘制直线的过程。
实例3-4:在OpenCV-Python图像中绘制直线
源码路径:daima\3\cv04.py
- import cv2 as cv
-
- # 创建黑色的图像
-
- img = cv.imread('111.jpg',1)
-
- # 绘制一条厚度为5的蓝色对角线
-
- cv.line(img,(0,0),(511,511),(255,0,0),5)
-
- #显示图像
-
- cv.imshow('image',img)
-
- cv.waitKey(0)
在上述代码中,(0,0)表示起点,(511,511)表示终点,(255,0,0)表示线的颜色,5表示线的宽度。执行效果如图3-4所示。
(2)画矩形
在OpenCV-Python中使用内置函数cv.rectangle()绘制矩形,在绘制时需要矩形的左上角和右下角。请看下面的代码,将在图像img的右上角绘制一个绿色矩形。
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
(3)画圆
在OpenCV-Python中使用内置函数cv.circle()绘制圆,在绘制时需要设置圆的中心坐标和半径。例如:
cv.circle(img,(447,63), 63, (0,0,255), -1)
(4)画椭圆
在OpenCV-Python中使用内置函数cv.ellipse()绘制椭圆,在绘制时需要传递如下参数:
例如下面的代码绘制了一个椭圆:
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
(5)画多边形
在OpenCV-Python中使用内置函数cv.polylines()绘制多边形,在绘制时时首先需要设置顶点坐标,将这些点组成形状为ROWS*1*2的数组,其中ROWS是顶点数,并且其类型应为int32。例如下面绘制了一个带有四个顶点的黄色小多边形。
- pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
- pts = pts.reshape((-1,1,2))
- cv.polylines(img,[pts],True,(0,255,255))
注意,如果函数cv.polylines()的第三个参数为False,将获得一条连接所有点的折线,而不是闭合形状。
(6)绘制文本:
在图像中绘制文本时需要设置多个内容参数,例如要写入的文字数据、要放置它的位置坐标(即数据开始的左下角)、字体类型、字体比例(指定字体大小)、例如颜色、厚度、线条类型等。为了获得更好的外观,建议使用lineType = cv.LINE_AA。请看下面的代码,将在白色图像上绘制文字“OpenCV”。
- font = cv.FONT_HERSHEY_SIMPLEX
- cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)
请看下面的实例,我们将对上面的代码进行总结,演示使用OpenCV-Python中绘制常见图形的过程。
实例3-5:绘制常见的图形
源码路径:daima\3\cv05.py
- import numpy as np
- import cv2 as cv
- # 创建黑色的图像
- img = np.zeros((512,512,3), np.uint8)
- # 绘制一条厚度为5的蓝色对角线
- cv.line(img,(0,0),(511,511),(255,0,0),5)
-
- cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
-
- cv.circle(img,(447,63), 63, (0,0,255), -1)
-
- cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
-
- pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
- pts = pts.reshape((-1,1,2))
- cv.polylines(img,[pts],True,(0,255,255))
-
- font = cv.FONT_HERSHEY_SIMPLEX
- cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)
-
- #显示图像
- cv.imshow('image',img)
- cv.waitKey(0)
执行效果如图3-5所示。
图3-5 执行效果
在使用电脑绘图时,通常将鼠标作为画笔。假设我们即将创建一个应用程序,要求在双击鼠标后可以在图像上绘制一个圆。为了实现这个功能,首先创建一个鼠标回调函数,该函数在发生鼠标事件时执行。鼠标事件可以是与鼠标相关的任何事物,例如左键按下,左键按下,左键双击等。它为我们提供了每个鼠标事件的坐标(x,y)。通过此活动和地点,我们可以做任何我们喜欢的事情。通过如下Python代码,可以输出显示所有可用的鼠标事件。
- import cv2 as cv
- events = [i for i in dir(cv) if 'EVENT' in i]
- print( events )
在作者的电脑中执行后会输出显示OpenCV-Python支持的鼠标事件:
['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON', 'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN', 'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK', 'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']
'运行
请看下面的实例,功能是创建一个矩形画布,当双击鼠标左键时调用函数draw_circle()绘制一个指定样式的圆。
实例3-6:绘制一个指定样式的圆
源码路径:daima\3\cv06.py
- import numpy as np
- import cv2 as cv
- # 鼠标回调函数
- def draw_circle(event,x,y,flags,param):
- if event == cv.EVENT_LBUTTONDBLCLK:
- cv.circle(img,(x,y),100,(222,220,0),-1)
- # 创建一个黑色的图像,一个窗口,并绑定到窗口的功能
- img = np.zeros((512,512,3), np.uint8)
- cv.namedWindow('image')
- cv.setMouseCallback('image',draw_circle)
- while(1):
- cv.imshow('image',img)
- if cv.waitKey(20) & 0xFF == 27:
- break
- cv.destroyAllWindows()
执行效果如图3-6所示。
图3-6 当双击鼠标左键时绘制圆
在OpenCV-Python中使用内置函数cv.getTrackbarPos()创建滑块,例如:
cv.createTrackbar('R','image',0,255,nothing)
在函数cv.getTrackbarPos()中,第一个参数表示滑块的名称,第二个参数是滑块附加到的窗口的名称,第三个参数是默认值,第四个参数是最大值,第五个是执行的回调函数每次跟踪栏值更改。
在下面的实例中,使用内置函数cv.getTrackbarPos()创建滑块,通过滑块可以设置屏幕的颜色。执行后先显示设置颜色窗口,以及三个用于指定B、G、R颜色的跟踪栏。通过滑动滑块可以相应地更改窗口的颜色。在默认情况下,初始颜色将设置为黑色。
实例3-7:通过滑块设置屏幕的颜色
源码路径:daima\3\cv07.py
- import numpy as np
- import cv2 as cv
- def nothing(x):
- pass
- # 创建一个黑色的图像,一个窗口
- img = np.zeros((300,512,3), np.uint8)
- cv.namedWindow('image')
- # 创建颜色变化的轨迹栏
- cv.createTrackbar('R','image',0,255,nothing)
- cv.createTrackbar('G','image',0,255,nothing)
- cv.createTrackbar('B','image',0,255,nothing)
- # 为 ON/OFF 功能创建开关
- switch = '0 : OFF \n1 : ON'
- cv.createTrackbar(switch, 'image',0,1,nothing)
- while(1):
- cv.imshow('image',img)
- k = cv.waitKey(1) & 0xFF
- if k == 27:
- break
- # 得到四条轨迹的当前位置
- r = cv.getTrackbarPos('R','image')
- g = cv.getTrackbarPos('G','image')
- b = cv.getTrackbarPos('B','image')
- s = cv.getTrackbarPos(switch,'image')
- if s == 0:
- img[:] = 0
- else:
- img[:] = [b,g,r]
- cv.destroyAllWindows()
在上述代码中,我们创建了一个画笔开关,只有在该开关为ON的情况下,才能使用滑块设置屏幕的颜色,否则屏幕始终为黑色。执行效果如图3-7所示。
图3-7 执行效果
(1)访问和修改像素值
首先加载一幅指定的彩色图像:
- >>> import numpy as np
-
- >>> import cv2 as cv
-
- >>> img = cv.imread('111.jpg')
接下来可以通过行和列坐标来访问图像的像素值。对于BGR图像来说,会返回一个由蓝色、绿色和红色值组成的数组。对于灰度图像来说,只会返回相应的灰度。
- >>> px = img[100,100]
-
- >>> print( px )
-
- [157 166 200]
-
- # 仅访问蓝色像素
-
- >>> blue = img[100,100,0]
-
- >>> print( blue )
-
- 157
也可以用相同的方式修改图像的像素值:
- >>> img[100,100] = [255,255,255]
-
- >>> print( img[100,100] )
-
- [255 255 255]
也可以用下面的方法访问和修改像素值:
- # 访问 RED 值
-
- >>> img.item(10,10,2)
-
- 59
-
- # 修改 RED 值
-
- >>> img.itemset((10,10,2),100)
-
- >>> img.item(10,10,2)
-
- 100
(2)访问图像属性
图像属性包括行数,列数和通道数,图像数据类型,像素数等。在OpenCV-Python中,可以通过img.shape访问图像的形状。img.shape会返回由行、列和通道数组成的元组(如果图像是彩色的),例如:
- >>> print( img.shape )
-
- (342, 548, 3)
注意:如果图像是灰度模式,则返回的元组仅包含行数和列数,因此这是检查加载的图像是灰度还是彩色的好方法。
可以通过访问img.size获得图像的像素总数:
- >>> print( img.size )
- 562248
可以通过img.dtype获得图像的数据类型:
- >>> print( img.dtype )
-
- uint8
(3)为图像设置边框(填充)
如果要在图像周围创建边框(如相框),可以使用OpenCV-Python内置函数cv.copyMakeBorder()实现。函数cv.copyMakeBorder()在卷积运算和零填充等方面的应用比较常见,此函数的常用参数如下:
请看下面的实例,演示了使用函数cv.copyMakeBorder()为图像设置边框的过程。在Matplotlib中,为图像111.jpg设置了多种样式的边框。
实例3-8:为图像设置多种样式的边框
源码路径:daima\3\cv08.py
- import cv2 as cv
- import numpy as np
- from matplotlib import pyplot as plt
- BLUE = [255,0,0]
- img1 = cv.imread('111.jpg')
- replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
- reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
- reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
- wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
- constant= cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_CONSTANT,value=BLUE)
- plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
- plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
- plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
- plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
- plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
- plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
- plt.show()
执行效果如图3-8所示。
图3-8 执行效果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。