OpenCV 入门01
参考资料:
http://www.woshicver.com/ OpenCV-Python 中文文档
图像入门:
如何读取图像,如何显示图像以及如何将其保存 cv.imread(),cv.imshow(),cv.imwrite()
读取,展示,保存图片:
import cv2 as cv img = cv.imread("d:/test/1.jpg",cv.IMREAD_COLOR) # 读取 cv.imshow("hello OpenCV",img) # 显示 cv.imwrite("d:/test/1.png",img) # 保存 cv.waitKey(0) cv.destroyAllWindows()
import cv2 as cv img = cv.imread("d:/test/1.jpg",cv.IMREAD_COLOR) # 读取 cv.imshow("hello OpenCV",img) # 显示 cv.imwrite("d:/test/1.png",img) # 保存 retKey = cv.waitKey(0) if retKey == 27: # 等待ESC退出 ESC的ASCII值为27 cv.destroyAllWindows() elif retKey == ord('s'): # 如果用户输入的是 s ,保存和退出 cv.imwrite('mysave.png',img) cv.destroyAllWindows()
使用matplotlib:
Matplotlib是Python的绘图库,可为你提供多种绘图方法。你将在接下来的文章中看到它们。在这里,你将学习如何使用Matplotlib显示图像。你可以使用Matplotlib缩放图像,保存图像等。
import cv2 as cv import matplotlib.pyplot as plt img = cv.imread("d:/test/4.jpg",cv.IMREAD_COLOR) # 读取 plt.imshow(img,cmap="gray") plt.xticks([]) # 隐藏 x 轴和 y 轴上的刻度值 plt.yticks([]) plt.show()
注:
OpenCV加载的彩色图像处于BGR模式。但是Matplotlib以RGB模式显示。因此,如果使用OpenCV读取彩色图像,则Matplotlib中将无法正确显示彩色图像,解决方法见下面。
将OpenCV 的bgr 变为 rgb :
import cv2 as cv import matplotlib.pyplot as plt img = cv.imread("d:/test/4.jpg",cv.IMREAD_COLOR) # 读取 # print(img.shape) (1080, 1920, 3) H W C img = img[:,:,::-1] # 将OpenCV的bgr 转为 rgb plt.imshow(img) plt.xticks([]) # 隐藏 x 轴和 y 轴上的刻度值 plt.yticks([]) plt.show()
此时,彩色图片就显示正常了 ,
或者使用 cv.CvtColor() 方法:
import cv2 as cv import matplotlib.pyplot as plt img = cv.imread("d:/test/4.jpg",cv.IMREAD_COLOR) # 读取 # img = img[:,:,::-1] # 将OpenCV的bgr 转为 rgb img = cv.cvtColor(img,cv.COLOR_BGR2RGB) plt.imshow(img) plt.xticks([]) # 隐藏 x 轴和 y 轴上的刻度值 plt.yticks([]) plt.show()
视频入门:
读取视频,显示视频和保存视频 cv.VideoCapture(),cv.VideoWriter()
01摄像机捕捉实时画面:
import cv2 as cv cap = cv.VideoCapture(0) if not cap.isOpened(): print("Cannot open camera") exit() # 修改窗口的 宽高 cap.set(cv.CAP_PROP_FRAME_WIDTH,320) cap.set(cv.CAP_PROP_FRAME_HEIGHT,240) while True: # 逐帧捕获 ret,frame = cap.read() # 如果正常读取帧 ret 为True if not ret: print("Cannot receive frame.Exiting...") break # gray = cv.cvtColor(frame,cv.COLOR_BGR2RGB) cv.imshow('frame',frame) if cv.waitKey(1) == ord('q'): break cap.release() cv.destroyAllWindows()
02从文件播放视频:
import cv2 as cv if __name__ == '__main__': cap = cv.VideoCapture("d:/test/a.mp4") while cap.isOpened(): ret, frame = cap.read() # 如果正确读取 ret 为True if not ret: print("can't receive frame. Exiting...") break gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) cv.imshow('frame', gray) # 1ms 等待按键1ms,如果没有按键返回-1 if cv.waitKey(1) == ord('q'): break cap.release() cv.destroyAllWindows()
保存视频:
import cv2 as cv if __name__ == '__main__': cap = cv.VideoCapture(0) # 定义编解码器并创建VideoWriter对象 fourcc = cv.VideoWriter_fourcc(*'XVID') out = cv.VideoWriter('d:/test/output.avi', fourcc, 20.0, (640, 480)) while cap.isOpened(): ret, frame = cap.read() if not ret: print("Can't receive frame (stream end?). Exiting ...") break frame = cv.flip(frame, 0) # 写翻转后的frame out.write(frame) cv.imshow('frame', frame) if cv.waitKey(1) == ord('q'): break # 完成工作后释放所有内容 cap.release() out.release() cv.destroyAllWindows()
绘图功能:
opencv 中的绘图功能,cv.line(),cv.circle(),cv.rectangle(),cv.ellipse(),cv.putText()
基本绘图:
import numpy as np import cv2 as cv # 创建黑色的图像 img = np.zeros((512,512,3), np.uint8) # img:您要绘制形状的图像 # color:形状的颜色。对于BGR,将其作为元组传递,例如:(255,0,0)对于蓝色。对于灰度,只需传递标量值即可。 # 厚度:线或圆等的粗细。如果对闭合图形(如圆)传递-1 ,它将填充形状。默认厚度= 1 # lineType:线的类型,是否为8连接线,抗锯齿线等。默认情况下,为8连接线。**cv.LINE_AA**给出了抗锯齿的线条,看起来非常适合曲线。 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) # -1 表示完全填充整个圆 cv.ellipse(img,(256,256),(100,50),0,0,180,(0,255,0),-1) # 中心 (256,256) # 轴长度(100,50) #0 0->180 pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32) pts = pts.reshape((-1,1,2)) # 即 (4,1,2)的形状 vecx1x2 的数组 固定格式 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('hello world',img) cv.waitKey(0) cv.destroyAllWindows()
解决putText() 不能显示中文问题:
import numpy as np import cv2 as cv from PIL import Image, ImageDraw, ImageFont # 创建黑色的图像 img = np.zeros((512,512,3), np.uint8) # 方法: # OpenCV图片格式转换成PIL的图片格式; # 使用PIL绘制文字; # PIL图片格式转换成OpenCV的图片格式; img = Image.fromarray(cv.cvtColor(img, cv.COLOR_BGR2RGB)) draw = ImageDraw.Draw(img) font = ImageFont.truetype("msyh.ttc", 30, encoding="utf-8") draw.text((10, 400), "牛牛牛",(255,0,0),font=font) # 这里的颜色是 RGB img = cv.cvtColor( np.asarray(img),cv.COLOR_RGB2BGR) # 转回 opencv 格式 cv.imshow('hello world',img) cv.waitKey(0) cv.destroyAllWindows()
鼠标作为画笔:
OpenCV中处理鼠标事件 cv.setMouseCallback()
双击鼠标画圆形:
import numpy as np import cv2 as cv # 鼠标回调函数 def draw_circle(event, x, y, flags, param): if event == cv.EVENT_LBUTTONDBLCLK: print(flags, param) cv.circle(img, (x, y), 100, (231, 123, 176), -1) if __name__ == '__main__': # 创建一个黑色的图像,一个窗口,并绑定到窗口的功能 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: # ESC 键 break cv.destroyAllWindows()
移动鼠标画:
import cv2 as cv import numpy as np drawing = False # 如果按下鼠标,则为真 mode = True # 如果为真,绘制矩形。按 m 键可以切换到曲线 ix,iy = -1,-1 # 鼠标回调函数 def draw_circle(event,x,y,flags,param): global ix,iy,drawing,mode if event == cv.EVENT_LBUTTONDOWN: drawing = True ix,iy = x,y elif event == cv.EVENT_MOUSEMOVE: if drawing == True: if mode == True: cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) else: cv.circle(img,(x,y),50,(0,0,255),-1) elif event == cv.EVENT_LBUTTONUP: drawing = False if mode == True: cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) else: cv.circle(img,(x,y),50,(0,0,255),-1) if __name__ == '__main__': # 创建一个黑色的图像,一个窗口,并绑定到窗口的功能 img = np.zeros((512, 512, 3), np.uint8) cv.namedWindow('image') cv.setMouseCallback('image', draw_circle) while (1): cv.imshow('image', img) code = cv.waitKey(20) if code == 27: break elif code == ord('m'): mode = False cv.destroyAllWindows()
点击m 键切换曲线,
扩展--如何绘制未填充的矩形:
import cv2 as cv import numpy as np drawing = False # 如果按下鼠标,则为真 mode = True # 如果为真,绘制矩形。按 m 键可以切换到曲线 ix, iy = -1, -1 # 鼠标回调函数 def draw_circle(event, x, y, flags, param): global ix, iy, drawing, mode if event == cv.EVENT_LBUTTONDOWN: drawing = True ix, iy = x, y # elif event == cv.EVENT_MOUSEMOVE: # if drawing == True: # if mode == True: # cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1) # else: # cv.circle(img, (x, y), 50, (0, 0, 255), 1) elif event == cv.EVENT_LBUTTONUP: drawing = False if mode == True: cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1) else: cv.circle(img, (x, y), 50, (0, 0, 255), 1) if __name__ == '__main__': # 创建一个黑色的图像,一个窗口,并绑定到窗口的功能 img = np.zeros((512, 512, 3), np.uint8) cv.namedWindow('image') cv.setMouseCallback('image', draw_circle) while (1): cv.imshow('image', img) code = cv.waitKey(20) if code == 27: break elif code == ord('m'): mode = not mode cv.destroyAllWindows()
Trackbar作为调色板:
将轨迹栏固定到OpenCV窗口 cv.getTrackbarPos,cv.createTrackbar
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 功能创建开关 cv.createTrackbar('0:OFF|1:ON', 'image', 0, 1, nothing) while 1: cv.imshow('image', img) k = cv.waitKey(1) if k == 27: break # 得到四条轨迹的当前数值 r = cv.getTrackbarPos('R', 'image') g = cv.getTrackbarPos('G', 'image') b = cv.getTrackbarPos('B', 'image') s = cv.getTrackbarPos('0:OFF|1:ON', 'image') if s == 0: img[:] = 0 else: img[:] = [b, g, r] cv.destroyAllWindows()
练习题:
使用Trackbar创建颜色和画笔半径可调的Paint应用程序。有关绘制的信息,请参阅有关鼠标处理的先前例子。
import numpy as np import cv2 as cv drawing = False ix, iy = -1, -1 r,g,b,radius = 0,0,0,0 # 鼠标回调函数 def draw_circle(event, x, y, flags, param): global ix, iy, drawing,r,g,b,radius if event == cv.EVENT_LBUTTONDOWN: drawing = True ix, iy = x, y elif event == cv.EVENT_LBUTTONUP: drawing = False cv.rectangle(img, (ix, iy), (x, y), (b, g, r), radius) def nothing(x): pass if __name__ == '__main__': # 创建一个黑色的图像,一个窗口 img = np.zeros((300, 512, 3), np.uint8) cv.namedWindow('image') cv.setMouseCallback('image', draw_circle) # 创建颜色变化的轨迹栏 cv.createTrackbar('R', 'image', 0, 255, nothing) cv.createTrackbar('G', 'image', 0, 255, nothing) cv.createTrackbar('B', 'image', 0, 255, nothing) # 创建画笔半径 cv.createTrackbar('Radius', 'image', 1, 10, nothing) while 1: cv.imshow('image', img) k = cv.waitKey(1) if k == 27: break # 得到四条轨迹的当前数值 r = cv.getTrackbarPos('R', 'image') g = cv.getTrackbarPos('G', 'image') b = cv.getTrackbarPos('B', 'image') radius = cv.getTrackbarPos('Radius', 'image') cv.destroyAllWindows()