opencv十四天入门学习——task5

前言

本次是opencv学习的任务五,主要包含鼠标操作与响应、图像像素类型转换与归一化、图像几何变换、视频读写处理四部分学习内容。通过观看视频、了解相关功能的含义与API函数,再进行代码的实践,从理论到实践熟悉了解opencv,我对opencv有了更多的掌握。

1、鼠标操作与响应

注册回调函数:

void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);
功能:为指定的窗口设置鼠标处理程序
参数:winname表示窗体的名称;onMouse表示鼠标事件的回调函数;param表示传递给回调函数的可选参数。

回调函数方法:

typedef void (MouseCallback)(int event, int x, int y, int flags, void userdata);

event是cv::MouseEventTypes 的常量之一;x是鼠标事件的x坐标,y鼠标事件的y坐标;flags是cv::MouseEventFlags 的常量之一;userdata 可选参数。

EVENT_LBUTTONDOWN、EVENT_MOUSEMOVE、EVENT_LBUTTONUP是三个非常重要的鼠标事件(MouseEventFlags ),分别表示鼠标左键按下,鼠标移动,鼠标左键弹起。

实验代码:

import cv2 as cv
import numpy as np

b1 = cv.imread("./apple.jpg")
img = np.copy(b1)
x1 = -1
x2 = -1
y1 = -1
y2 = -1

def mouse_drawing(event, x, y, flags, param):
    global x1, y1, x2, 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


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

实验结果:
在这里插入图片描述

2、图像像素类型转换与归一化

图像处理中,图像单通道像素值为0255之间的uchar类型,使用归一化将其转化为01区间之间可以在改变数据的分布和信息存储的前提下加速后续网络的计算。

归一化函数:void cv::normalize(InputArry src,InputOutputArray dst,double alpha=1,double beta=0,int norm_type=NORM_L2,int dtype=-1,InputArray mark=noArry())

参数:

src 输入数组;
dst 输出数组,数组的大小和原数组一致;
alpha 1表示用来规范值,2表示规范范围,并且是下限;
beta 规范范围并且是上限;
norm_type 归一化方法类型;
dtype 负值表示输出在大小深度通道数都等于输入,正值表示输出只在深度与输如不同,不同的地方由dtype决定;
mark 掩码。选择感兴趣区域,选定后只能对该区域进行操作。

数学公式类型:

NORM_MINMAX

NORM_INF

NORM_L1

NORM_L2

最常用 NORM_MINMAX

实验代码:

import cv2 as cv
import numpy as np

def trackbar_callback(pos):
    print(pos)

image_uint8 = cv.imread("./butterfly.jpg")
cv.imshow("image_uint8", image_uint8)
img_f32 = np.float32(image_uint8)
cv.imshow("img32", img_f32)
cv.normalize(img_f32, img_f32, 1, 0, cv.NORM_MINMAX)
cv.imshow("norm-imgf32", img_f32)

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.waitKey(0)
cv.destroyAllWindows()

实验结果:
在这里插入图片描述

3、图像几何变换

平移矩阵
在这里插入图片描述
旋转矩阵
在这里插入图片描述
opencv中的函数API:

(1)仿射变换:cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]] ) -> dst

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

(2)旋转矩阵获取:cv.getRotationMatrix2D

Center表示旋转中心, angle表示度数,大于零表示逆时针旋转, scale表示放缩尺度大小。

(3)翻转:cv.flip(src, flipCode[, dst] ) ->dst

src表示输入图像,flipCode支持0水平、1垂直,-1对角线翻转。

(4)特殊角度旋转:cv.rotate(src, rotateCode[, dst] ) -> dst

src表示输入图像,rotateCode支持旋转90°,180°,270°。

(5)缩放函数:dst = cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

src表示输入图像, dst为缩放后的图像,fx,fy为图像x,y方向的缩放比例,interplolation为缩放时的插值方式,支持立方插值、双线形插值、最近邻插值、像素关系重采样等方法 。

实验代码:

import cv2 as cv
import numpy as np

image = cv.imread("./apple.jpg")
cv.imshow("apple", image)
h, w, c = image.shape
cx = int(w / 2)
cy = int(h / 2)
M = np.zeros((2, 3), dtype=np.float32)
M[0, 0] = .5
M[1, 1] = .5
M[0, 2] = 50
M[1, 2] = 50
print("M(2x3) = \n", M)
dst = cv.warpAffine(image, M, (cx, cy))
cv.imshow("translate-demo", dst)

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

实验结果:
在这里插入图片描述

4、视频读写处理

视频格式有SD(Standard Definition)标清480P、HD(High Definition)高清720P/1080P、UHD(Ultra High Definition)超高清4K/2160P;分辨率有SD-640x480,HD-960x720,UHD-4K等。

(1)视频读取函数:cv.VideoCapture(filename/Index,apiPreference ,params)

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

(2)查看视频属性: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

(3)视频文件保存:cv.VideoWriter( filename, fourcc,fps, frameSize [, isColor] ) ->

filename表示保存文件名称,fourcc表示编码方式,fps表示帧率,frameSize表示视频帧大小,与实现大小相符。

实验代码:

import cv2 as cv
import numpy as np

cap = cv.VideoCapture("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)
fourcc = cap.get(cv.CAP_PROP_FOURCC)
writer = cv.VideoWriter("output.mp4", int(fourcc), fps, (int(frame_w), int(frame_h)))
while True:
    ret, frame = cap.read()
    if ret is not True:
        break
    cv.imshow("frame", frame)
    c = cv.waitKey(1)
    if c == 27:
        break
    writer.write(frame)

cv.waitKey(0)
cv.destroyAllWindows()

实验结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独孤西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值