openCV-Task05:17-20 17:鼠标操作与响应;18:图像像素转换与归一化;19:图像几何变换;20:视频读写处理

目录

 鼠标操作与响应

基本步骤

 绘制矩形

代码实现

运行结果

图像像素转换和归一化

 归一化的方式

使用函数及参数

数据转换

代码实现

运行结果

 图像几何变换

变换矩阵

代码实现

运行结果

 视频读写处理

视频清晰度

 视频读取函数

查询视频方法 

视频保存

代码实现 

运行结果


 鼠标操作与响应

基本步骤

鼠标左键按下

EVENT_LBUTTONDOWN

 鼠标移动

EVENT_MOUSEMOVE

 鼠标左键弹起

EVENT_LBUTTONUP

 绘制矩形

鼠标左键按下为矩形左上角

鼠标移动为绘制矩形的大小

鼠标左键弹起为矩形的最终大小

代码实现(回调和实现功能的函数)

b1 = cv.imread(".\\data\\girl.jpg")
img = np.copy(b1)
x1 = -1  # 初始化坐标
y1 = -1
x2 = -1
y2 = -1


def mouse_drawing(event, x, y, flags, param):
    global x1, x2, y1, y2
    if event == cv.EVENT_LBUTTONDOWN:
        x1 = x
        y1 = y
    if event == cv.EVENT_MOUSEMOVE:
        if x1 < 0 or y1 < 0:  # 没有移动,直接返回空
            return
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            b1[:, :, :] = img[:, :, :]  # 每次都擦除上一次的绘画
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0)
    if event == cv.EVENT_LBUTTONUP:
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            b1[:, :, :] = img[:, :, :]
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0)
        x1 = -1
        x2 = -1
        y1 = -1
        y2 = -1
def mouse_demo():
    cv.namedWindow("mouse demo", cv.WINDOW_AUTOSIZE)
    cv.setMouseCallback("mouse demo", mouse_drawing)
    while True:
        cv.imshow("mouse demo", b1)
        c = cv.waitKey(10)
        if c == 27:
            break
    cv.destroyAllWindows()

运行结果

                             

图像像素转换和归一化

 归一化的方式

L1范式:NORM_L1

原始像素值除以所有像素值之和即为原始像素值归一化后的值。

L2范式:NORM_L2

原始像素值除以所有原始像素值平方值之和的平方根即为原始像素值归一化后的值。

最大值最小值归一化:NORM_L1

原始像素值除以所有原始像素值中的最大值即为原始像素值归一化后的值。

INF归一化:NORM_INF

原始像素值除以所有原始像素值中的最大值即为原始像素值归一化后的值。

使用函数及参数

cv.normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]	) -> dst
src表示输入图像, dst表示输出图像
alpha, beta 默认是1, 0,是归一化的区间值
norm_type默认是NORM_L2, 
norm_type常用是NORM_MINMAX

数据转换

Imread读入默认是uint8, 转换为float32,通过imshow显示之前,必须归一化到[0~1]之间。

代码实现

 image_uint8 = cv.imread(".\\data\\girl.jpg")  # 读取的图像是uint8型
    cv.imshow("image uint8", image_uint8)
    img_f32 = np.float32(image_uint8)  # 图像转换为float32
    cv.imshow("img32", img_f32)
    cv.normalize(img_f32, img_f32, 1, 0, cv.NORM_MINMAX)  # 归一化到0-1之间
    cv.imshow("norm-imgf32", img_f32)
    cv.waitKey(0)
    cv.destroyAllWindows()
    # 绘制滚动条
    cv.namedWindow("norm-demo", cv.WINDOW_AUTOSIZE)
    cv.createTrackbar("normtype", "norm-demo", 0, 3, trackbar_callback)
    while True:
        dst = np.float32(image_uint8)
        pos = cv.getTrackbarPos("normtype", "norm-demo")
        if pos == 0:
            cv.normalize(dst, dst, 1, 0, cv.NORM_MINMAX)
        if pos == 1:
            cv.normalize(dst, dst, 1, 0, cv.NORM_L1)
        if pos == 2:
            cv.normalize(dst, dst, 1, 0, cv.NORM_L2)
        if pos == 3:
            cv.normalize(dst, dst, 1, 0, cv.NORM_INF)
        cv.imshow("norm-demo", img_f32)
        c = cv.waitKey(50)
        if c == 27:
            break
        cv.destroyAllWindows()

运行结果

 

                            

 创建滚动条,选择0,显示MINMAX归一化的结果;1表示L1归一化的结果;2表示L2归一化的结果;3表示INF归一化的结果。

 图像几何变换

变换矩阵

cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]	) -> dst

src表示输入图像
M 表示2x3变换矩阵
dsize表示目标图像dst的大小
支持平移变换、放缩变换、旋转变换

对原图像左乘一个变换矩阵加上偏置,形成一个增广矩阵

平移:例如对图像整体向左向下平移100个像素点

放缩:例如对图像大小变为原来的1/2

旋转

注意:因为opencv是以图像的左上角为中心的,所以先要把中心位置平移到中心位置。

旋转矩阵获取cv.getRotationMatrix2D
Center表示旋转中心, angle表示度数,大于零表示逆时针旋转, scale表示放缩尺度大小。

cv.flip(src, flipCode[, dst]	) ->dst
cv.rotate(src, rotateCode[, dst]	) -> dst
src表示输入图像
flipCode支持0水平、1垂直,-1对角线翻转,
rotateCode支持旋转90°,180°,270°

代码实现

 image = cv.imread(".\\data\\lena.jpg")
    h, w, c = image.shape
    cx = int(w / 2)
    cy = int(h / 2)
    cv.imshow("image", image)
    M = np.zeros((2, 3), dtype=np.float32)
    M[0, 0] = .7
    M[1, 1] = .7
    M[0, 2] = 0
    M[1, 2] = 0
    print("M(2x3) = \n", M)
    dst = cv.warpAffine(image, M, (int(w * .7), int(h * .7)))
    cv.imshow("rescale-demo", dst)
    cv.imwrite("D:/result.png", dst)
    cv.imshow("rescale-demo", dst)
    cv.imwrite("D:/result.png", dst)
    # 获取旋转矩阵,degree > @表示逆时针旋转,原点在左上角M = cv.getRotationMatrix2D((w/2,h/2),45.0,1.0)dst = cv.warpAffine(image,M,(w,h))cv.imshow("rotate-demo", dst)
    dst = cv.flip(image, 0)
    cv.imshow("flip-demo", dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

运行结果

                                   

 视频读写处理

视频清晰度

SD(Standard Definition) 标清 480P
HD(High Definition) 高清 720P/1080P
UHD(Ultra High Definition) 超高清 4K/2160P
分辨率表示
SD-640x480, 704x480, 720x480, 848x480
HD-960x720,1280x720,1440x1080,1920x1080
UHD-4K,2160P

 视频读取函数

 
filename 表示视频文件
Index 表示 USB 摄像头或者 web camera 的索引
apiPreference = CAP_ANY 意思自动决定第三方视频库如: cv.CAP_FFMPEG cv.CAP_DSHOW

查询视频方法 

VideoCaput的get方法
cv.CAP_PROP_FRAME_WIDT
cv.CAP_PROP_FRAME_HEIGHT
cv.CAP_PROP_FPS
cv.CAP_PROP_FOURCC
cv.CAP_PROP_FRAME_COUNT

视频保存

cv.VideoWriter(
filename, 保存文件名称
fourcc, 编码方式
fps,  帧率
frameSize 视频帧大小,与实现的大小相同
[, isColor]  ) ->  <VideoWriter object>

代码实现 

cap = cv.VideoCapture(".\\data\\vtest.avi")
    # 获取视频的帧率,宽度,高度
    fps = cap.get(cv.CAP_PROP_FPS)
    frame_w = cap.get(cv.CAP_PROP_FRAME_WIDTH)
    frame_h = cap.get(cv.CAP_PROP_FRAME_HEIGHT)
    print(fps, frame_w, frame_h)
    # encode mode
    # fourcc= cv.VideoWriter fourcc(x'vp09')
    fourcc = cap.get(cv.CAP_PROP_FOURCC)  # 获取编码格式,使用需要转换成一个int值
    # 生成一个MP4文件
    writer = cv.VideoWriter('output.mp4', int(fourcc), fps, (int(frame_w), int(frame_h)))
    # loop read frame until last frame
    while True:
        ret, frame = cap.read()
        if ret is not True:
            break
        Ycrcb = cv.cvtColor(frame,cv.COLOR_RGB2YCrCb)
        cv.imshow("Ycrcb",Ycrcb)
        cv.imshow("frame", frame)
        c = cv.waitKey(1)
        if c == 27:
            break
    cap.release()
    writer.release()

    cv.destroyAllWindows()

运行结果

                            

动态图

将视频每一帧(图片)提取出来,转换为Ycrcb图像后, 然后显示出来。

Ycrcb动态图

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值