OpenCV基础操作(1)图片、视频、绘图函数
import cv2 as cv
import numpy as np
1、图像的读取、显示、保存
'''
使用函数 cv2.imread() 读入图像。
第一个参数是幅图路径,
第二个参数是要告诉函数应该如何读取这幅图片。
• cv2.IMREAD_COLOR(1):读入一副彩色图像。图像的透明度会被忽略,这是默认参数。
• cv2.IMREAD_GRAYSCALE(0):以灰度模式读入图像
• cv2.IMREAD_UNCHANGED(-1):读入一幅图像,并且包括图像的 alpha 通道
'''img = cv.imread('./img.jpg',cv.IMREAD_GRAYSCALE)
print(type(img),img.shape)
<class 'numpy.ndarray'> (494, 650)
'''
使用函数 cv2.imshow() 显示图像。窗口会自动调整为图像大小。
第一个参数是窗口的名字,其次才是我们的图像。
你可以创建多个窗口,只要你喜欢,但是必须给他们不同的名字cv2.waitKey() 是一个键盘绑定函数。需要指出的是它的时间尺度是毫秒级。
函数等待特定的几毫秒,看是否有键盘输入。特定的几毫秒之内,如果按下任意键,这个函数会返回按键的 ASCII 码值,程序将会继续运行。
如果没有键盘输入,返回值为 -1,如果我们设置这个函数的参数为 0,那它将会无限期的等待键盘输入。cv2.destroyAllWindows() 可以轻易删除任何我们建立的窗口。
如果你想删除特定的窗口可以使用 cv2.destroyWindow(),在括号内输入你想删除的窗口名
'''
cv.imshow('image',img)
cv.waitKey(0)
cv.destroyAllWindows()
'''
一种特殊情况是, 你也可以先创建一个窗口, 之后再加载图像。
这种情况下, 你可以决定窗口是否可以调整大小。
使用到的函数是cv2.namedWindow()。
初始设定函数标签是cv2.WINDOW_AUTOSIZE。
但是如果你把标签改成cv2.WINDOW_NORMAL,你就可以调整窗口大小了。
'''
cv.namedWindow('image',cv.WINDOW_NORMAL)
cv.imshow('image',img)
cv.waitKey(0)
cv.destroyAllWindows()
'''
保存图像
'''cv.imwrite('new_img.jpg',img)
True
'''
程序将会加载一个灰度图,显示图片,按下’s’键保存后退出,或者按下 ESC(k=27) 键退出不保存。
'''img = cv.imread('img.jpg',cv.IMREAD_GRAYSCALE)
cv.imshow('image',img)
k = cv.waitKey(0)
print(k)
if k == 27:cv.destroyAllWindows()
elif k == ord('s'):cv.imwrite('new.jpg',img)cv.destroyAllWindows()
115
2、使用matplotlib显示图像
from matplotlib import pyplot as pltimg = cv.imread('img.jpg',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
'''
彩色图像使用 OpenCV 加载时是 BGR 模式。但是 Matplotib 是 RGB模式。
所以彩色图像如果已经被 OpenCV 读取,那它将不会被 Matplotib 正确显示。如下图,与原图相比,在颜色上有很大改变
'''img = cv.imread('img.jpg')
plt.imshow(img)
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
'''
下面介绍几种解决方式:第一种方式,利用cv2的merge函数手动去合并。
'''
img = cv.imread('img.jpg')
b,g,r = cv.split(img)
img = cv.merge([r,g,b])plt.imshow(img)
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
'''
第二种方式,利用cv2提供的BGR2RGB函数
'''
img = cv.imread('img.jpg')
img = cv.cvtColor(img,cv.COLOR_BGR2RGB)plt.imshow(img)
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
'''
第三种方式,利用矩阵的翻转。(推荐)
因为图像本身就是一个矩阵,所以可以直接利用矩阵操作实现图像通道的变换。
恰好opencv的[B,G,R] 与matplotlib的[R,G,B]刚好是逆序,所以可以很方便的利用矩阵的逆序操作。
'''
img = cv.imread('img.jpg')
img = img[:, :, ::-1]plt.imshow(img)
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
3、视频的读取及显示
'''
1、使用摄像头来捕获视频我们经常需要使用摄像头捕获实时图像。OpenCV 为这中应用提供了一个非常简单的接口。
我们使用摄像头来捕获一段视频,并把它转换成灰度视频显示出来。
''''''
你可以使用函数 cap.get(propId) 来获得视频的一些参数信息。这里propId 可以是 0 到 18 之间的任何整数。每一个数代表视频的一个属性。其中的一些值可以使用 cap.set(propId,value) 来修改,value 就是你想要设置成的新值。
例如,可以使用 cap.get(3) 和 cap.get(4) 来查看每一帧的宽和高。默认情况下得到的值是 640X480。
但是我可以使用 ret=cap.set(3,320)和 ret=cap.set(4,240) 来把宽和高改成 320X240
'''cap = cv.VideoCapture(0)while(True):# 一帧一帧的捕获# ret 返回一个布尔值(True/False)。如果帧读取的是正确的,就是 True。# 所以最后你可以通过检查他的返回值来查看视频文件是否已经到了结尾。# frame 是numpy.ndarrayret, frame = cap.read()# 将图像准换为灰度图gray = cv.cvtColor(frame,cv.COLOR_BGR2GRAY)# 一帧一帧的展示出来cv.imshow('frame',gray)# 输入q结束捕获k = cv.waitKey(1)if k & 0xFF == ord('q'):break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
640.0
480.0
'''
2、从文件中播放视频在播放每一帧时,使用 cv2.waiKey() 设置适当的持续时间。如果设置的太低视频就会播放的非常快,如果设置的太高就会播放的很慢
(你可以使用这种方法控制视频的播放速度)。通常情况下 25 毫秒就可以了。
'''cap = cv.VideoCapture(0)'''
在我们捕获视频,并对每一帧都进行加工之后我们想要保存这个视频。
对于图片来时很简单只需要使用 cv2.imwrite()。但对于视频来说就要多做点工作。要创建一个 VideoWriter的对象。
确定一个输出文件的名字。
接下来指定 FourCC 编码。
播放频率和帧的大小也都需要确定。
最后一个是 isColor 标签。如果是 True,每一帧就是彩色图'''
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi',fourcc, 20.0, (640,480))while(cap.isOpened()):ret, frame = cap.read()if ret==True:frame = cv.flip(frame,0)# write the flipped frameout.write(frame)cv.imshow('frame',frame)if cv.waitKey(1) & 0xFF == ord('q'):breakelse:break# Release everything if job is finished
cap.release()
out.release()
cv.destroyAllWindows()
4、OpenCV中的常用绘图函数
cv2.line(),cv2.circle(),cv2.rectangle(),cv2.ellipse(),cv2.putText()
上面所有的这些绘图函数需要设置下面这些参数:
- img:你想要绘制图形的那幅图像。
- color:形状的颜色。以 RGB 为例,需要传入一个元组,例如:(255,0,0)代表蓝色。对于灰度图只需要传入灰度值。
- thickness:线条的粗细。如果给一个闭合图形设置为 -1,那么这个图形就会被填充。默认值是 1.
- linetype:线条的类型,8 连接,抗锯齿等。默认情况是 8 连接。cv2.LINE_AA为抗锯齿,这样看起来会非常平滑。
'''
1、画线
'''
img = np.zeros((512,512,3), np.uint8)
cv.line(img,pt1 = (0,0),pt2 = (511,511),color=(255,0,0),thickness = 5)
winname = 'example'
cv.namedWindow(winname)
cv.imshow(winname, img)
cv.waitKey(0)
cv.destroyWindow(winname)
'''
2、矩形需要告诉函数的左上角顶点pt1和右下角顶点的坐标pt2。
'''
img = np.zeros((512,512,3), np.uint8)
cv.rectangle(img,pt1 = (10,10), pt2 = (200,100),color=(0,255,0),thickness = 5)
winname = 'example'
cv.namedWindow(winname)
cv.imshow(winname, img)
cv.waitKey(0)
cv.destroyWindow(winname)
'''
3、要画圆的话,只需要指定圆形的中心点坐标center(宽度,长度)和半径大小radius。
'''
img = np.zeros((512,512,3), np.uint8)
cv.circle(img, center = (200,200), radius = 150,color=(0,0,255),thickness = 5)
winname = 'example'
cv.namedWindow(winname)
cv.imshow(winname, img)
cv.waitKey(0)
cv.destroyWindow(winname)
'''
4、画椭圆比较复杂,我们要多输入几个参数。一个参数是中心点的位置坐标center
下一个参数是长轴和短轴的长度axes
椭圆沿逆时针方向旋转的角度angle
椭圆弧演顺时针方向起始的角度startAngle和结束角度endAngle,如果是 0 很 360,就是整个椭圆。
'''
img = np.zeros((512,512,3), np.uint8)
cv.ellipse(img, center = (200,200), axes = (100,50),angle = 45,startAngle = 0,endAngle = 270,color=(0,0,255),thickness = -1)
winname = 'example'
cv.namedWindow(winname)
cv.imshow(winname, img)
cv.waitKey(0)
cv.destroyWindow(winname)
'''
5、绘制多边形画多边形,需要指点每个顶点的坐标。
用这些点的坐标构建一个大小等于行数 X1X2 的数组,行数就是点的数目。这个数组的数据类型必须为 int32。isClosed是 False,我们得到的多边形是不闭合的(首尾不相连)
'''
img = np.zeros((512,512,3), np.uint8)
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
print(pts.shape)cv.polylines(img,[pts],isClosed = False,color=(0,0,255),thickness = 5)
winname = 'example'
cv.namedWindow(winname)
cv.imshow(winname, img)
cv.waitKey(0)
cv.destroyWindow(winname)
'''
6、在图片上添加文字要在图片上绘制文字,你需要设置下列参数:
• 你要绘制的文字text
• 你要绘制的位置org
• 字体类型fontFace(通过查看 cv2.putText() 的文档找到支持的字体)
• 字体的大小fontScale
• 文字的一般属性如颜色,粗细,线条的类型等。为了更好看一点推荐使用lineType=cv2.LINE_AA。'''
img = np.zeros((512,512,3), np.uint8)font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,text='OpenCV',org=(10,400), fontFace=font, fontScale=4,color = (255,255,255),thickness = 2,lineType=cv.LINE_AA)
winname = 'example'
cv.namedWindow(winname)
cv.imshow(winname, img)
cv.waitKey(0)
cv.destroyWindow(winname)