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()
View Code
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()
监控键盘事件,输入esc直接退出,输入s 保存退出

使用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()
View Code

注:

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()
View Code

此时,彩色图片就显示正常了 ,

或者使用 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()
View Code

视频入门:

读取视频,显示视频和保存视频 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()
View Code

保存视频:

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()
View Code

绘图功能:

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()
View Code

解决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()
View Code

鼠标作为画笔:

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()
View Code

移动鼠标画:

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()
view code

点击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()
View Code

Trackbar作为调色板:

将轨迹栏固定到OpenCV窗口 cv.getTrackbarPoscv.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()
View Code

练习题:

使用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()
调节画笔半径

原文地址:https://www.cnblogs.com/zach0812/p/13288556.html