目录
鼠标操作与响应
基本步骤
鼠标左键按下
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()
运行结果
视频读写处理
视频清晰度
视频读取函数
查询视频方法
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图像后, 然后显示出来。
