从零开始的Python图像识别-Week2 OpenCV入门

本周我们简单讲解了OpenCV官方的入门案例
内容有:
图像处理入门
视频处理入门
画图功能入门
鼠标事件入门
轨迹栏入门

OpenCV入门

图像处理入门

读取图像

使用函数cv.imread()读取图像。该映像应位于工作目录中,或者应提供完整的映像路径。

第二个参数是一个标志,用于指定应读取图像的方式。

  • cv.IMREAD_COLOR:加载彩色图像。图像的任何透明度都将被忽略。这是默认标志。
  • cv.IMREAD_GRAYSCALE:以灰度模式加载图像
  • cv.IMREAD_UNCHANGED:加载图像,包括alpha通道

注意
除了这三个标志,您可以分别简单地传递整数1、0或-1。

import cv2 as cv
import numpy as np
# 加载彩色图像
img1 = cv.imread('img1.jpg', cv.IMREAD_COLOR)
# 加载灰度图像
img2 = cv.imread('img2.jpg', cv.IMREAD_GRAYSCALE)

显示图像

使用函数cv.imshow()在窗口中显示图像。窗口自动适合图像尺寸。

第一个参数是窗口名称,它是一个字符串。第二个参数是我们的图像。您可以创建任意数量的窗口,但窗口名称必须不同。

cv.imshow('image1', img1)
cv.imshow('image2', img2)
cv.waitKey(0)
cv.destroyAllWindows()

显示效果如下:
彩色图像
灰度图像

写入图像

使用函数cv.imwrite()保存图像

第一个参数是文件名,第二个参数是要保存的图像。

若不指定保存路径,会将图像以PNG格式保存在工作目录中。

img2 = cv.imread('img2.jpg', cv.IMREAD_GRAYSCALE)
cv.imshow('image2', img2)
k = cv.waitKey(0)
if k == 27:          # 等待ESC键退出
    cv.destroyAllWindows()
elif k == ord('s'):  # 等待's'键保存并退出
    cv.imwrite('imgInGray.png', img2)
    cv.destroyAllWindows()

保存图片

视频处理入门

从相机捕获视频

通常,我们必须使用摄像机捕获实时流。OpenCV提供了一个非常简单的界面来执行此操作。让我们从笔记本相机捕获视频,将其转换为灰度视频并显示。

要捕获视频,您需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个摄像机的编号。通常,将连接一台摄像机(我以笔记本摄像头为例)。所以我只是传递0(或-1)。还可以通过传递1来选择第二台摄像机,依此类推。之后,就可以逐帧捕获。但最后,不要忘记释放捕获。

import numpy as np
import cv2 as cv

cap = cv.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    # 逐帧捕获图像
    ret, frame = cap.read()
    # 如果正确读取帧,ret为True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    # 对捕获的帧进行转换成灰度操作
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    # 显示结果帧
    cv.imshow('frame', gray)
    if cv.waitKey(1) == ord('q'):
        break
# 当完成所有操作后,释放捕获
cap.release()
cv.destroyAllWindows()

(当时晚上运行这个吓我一跳😫)

cap.read()返回布尔值(True/ False)。如果正确读取该帧,它将为True。因此,您可以通过检查此返回值来检查视频的结尾。

有时,cap可能尚未初始化捕获。在这种情况下,此代码显示错误。我们可以通过cap.isOpened()方法检查它是否已初始化。如果是True,那么初始化正常。否则,使用cap.open()打开它。

您还可以使用cap.get(propId)方法访问该视频的某些功能,其中propId是0到18之间的一个数字。每个数字表示视频的属性(如果适用于该视频)。

其中一些值可以使用cap.set(propId, value)进行修改。value即为你想要设置的值。

保存视频

我们捕获视频并对其进行逐帧处理,并且想要保存该视频。对于图像这非常简单:只需使用即可cv.imwrite()。而对于视频则需要做更多的工作。

这次我们创建一个VideoWriter对象。我们应该指定输出文件名(例如:output.avi)。然后,我们应指定FourCC代码(下一段中的详细解释)。接着应该传递每秒的帧数(fps)和帧大小。最后一个是isColor标志。如果为True,则编码器需要彩色框,否则将与灰度框一起使用。

FourCC是一个4字节的代码,用于指定视频编解码器。可用代码列表可在fourcc.org中找到。它取决于平台。以下编解码器对我来说很好用。

  • 在Fedora中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG会生成大尺寸的视频。X264会生成非常小的尺寸的视频)
  • 在Windows中:DIVX(尚待测试和添加)
  • 在OSX中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。
    FourCC代码作为MJPG的cv.VideoWriter_fourcc('M', 'J', 'P', 'G')cv.VideoWriter_fourcc(*'MJPG')传递。

以下代码从摄像机捕获,在垂直方向上翻转每一帧,然后保存视频。

import numpy as np
import cv2 as cv

cap = cv.VideoCapture(0)
# 定义编码器并创建 VideoWriter 对象
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('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)
    # 写入翻转的帧
    out.write(frame)
    cv.imshow('frame', frame)
    if cv.waitKey(1) == ord('q'):
        break
# 在操作完成后释放所有资源
cap.release()
out.release()
cv.destroyAllWindows()

画图功能

我们将用到一些常见的参数,如下所示:

  • img:您要绘制形状的图像
  • color:形状的颜色。对于BGR,将其作为元组传递,例如:(255,0,0)是蓝色。对于灰度,只需传递标量值即可。
  • thickness:线或圆等的粗细。如果对封闭的图形(如圆)传递-1,它将填充形状。默认厚度= 1
  • lineType:线的类型,是否为8-connected,抗锯齿线等。默认情况下,为8-connected。 cv.LINE_AA给出了抗锯齿的线条,看起来非常适合曲线。

绘制直线

要绘制一条直线,需要传递直线的起点和终点。我们将创建一个黑色图像,并从左上角到右下角在其上绘制一条蓝线。

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)

绘制椭圆

要绘制椭圆,我们需要传递几个参数。一个参数是中心位置(x,y)。下一个参数是轴长度(长轴长度,短轴长度)。angle是椭圆沿逆时针方向旋转的角度。startAngleendAngle表示从主轴沿顺时针方向测量的椭圆弧的开始和结束。即给定值0和360将画出完整的椭圆。下面的我们将在图像的中心绘制一个椭圆形。

cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

绘制多边形

要绘制多边形,首先需要确定顶点的坐标。将这些点组成形状为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)) # 如果第三个参数为False,我们将获得一条连接所有点的折线,而不是闭合形状。

向图像添加文本:

要将文本放入图像中,需要指定以下内容。

  • 要写入的文字数据
  • 要放置它的位置坐标
  • 字体类型(检查cv.putText()文档以获取受支持的字体)
  • 字体比例(指定字体大小)
  • 常规的内容,例如colorthicknesslineType等。为了获得更好的外观,建议使用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)

显示结果:

cv.imshow('the image', img)
cv.waitKey(0)
cv.destroyAllWindows()

图形功能示例

通过鼠标绘制图案

首先,我们创建一个鼠标回调函数,该函数在发生鼠标事件时执行。鼠标事件可以是与鼠标相关的任何事物,例如左键按下,左键松开,左键双击等。它为我们提供了每个鼠标事件的坐标(x,y)。通过此活动和地点,我们可以做任何我们喜欢的事情。

# 打印出所有可用事件
import cv2 as cv
events = [i for i in dir(cv) if 'EVENT' in i]
print( events )

打印结果有:
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

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,(255,0,0),-1)
# 创建一个黑色图像,并将该事件绑定到这个窗口上
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
    cv.imshow('image',img)
    # 按ESC键退出
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

效果如下:
鼠标画图示例

通过轨迹栏调色

我们将创建一个简单的应用程序,以显示指定的颜色。我们将创建一个显示颜色的窗口,以及三个用于指定B,G,R颜色的轨迹栏。滑动轨迹栏并相应地更改窗口颜色。默认情况下,初始颜色将设置为黑色。

对于cv.createTrackbar()函数,第一个参数是跟踪栏名称,第二个参数是其附加到的窗口名称,第三个参数是默认值,第四个参数是最大值,第五个参数是在每次跟踪栏值更改时执行的回调函数。回调函数始终具有默认参数,即轨迹栏位置。在我们的例子中,函数什么都不做,所以我们简单地让它pass

轨迹栏的另一个重要应用是将其用作按钮或开关。默认情况下,OpenCV不具有按钮功能。因此,您可以使用轨迹栏来获得此类功能。在我们的应用程序中,我们创建了一个开关,只有在该开关为ON的情况下,该应用程序才能在其中运行,否则屏幕始终为黑色。

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)
# 创建用于切换开/关功能的轨迹栏
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()

效果如下轨迹栏控制调色


这里是 咸鱼不垫底
不定时更新自己的学习经历,以及分享自己学到的知识!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值