python图像处理【学习笔记】(二)
1 引言上一篇学习了使用不同方法读取图像并显示。python图像处理【学习笔记】一接下来将整理图片保存视频读取保存以及对图像进行基本几何变换的内容。#写在前面#本系列文章是我在学习图像处理过程中的知识整理与实践记录。学习过程中使用了 OpenCV 等开源工具也参考了许多优秀的技术资料。在此感谢所有参与开源项目开发、维护以及知识分享的贡献者。正是开放、共享的开源精神让更多普通学习者有机会接触技术、理解原理并将所学知识应用到实际问题中!!!目录1 引言2 图片保存2.1 前文回顾读取图像并显示2.2 保存图像3 视频读取4 视频保存/录制5 图像的基本几何变换5.1 图像缩放5.2 图像裁剪5.3 图像翻转5.4 图像旋转固定角度旋转5.5 图像旋转任意角度旋转5.6 图像平移5.7 仿射变换5.8 透视变换6 常见问题7 总结2 图片保存为防止函数用法不熟这里先给出示例程序和效果然后根据效果逐步改进程序。形成一个比较清晰完整的脉络。最后再汇总函数的用法等等。2.1 前文回顾读取图像并显示示例程序如下import cv2 input_file rG:\Desktop\Image Processing\Test Dataset\test3.png #读取图像 image cv2.imread(input_file) #图像显示 cv2.imshow(image,image) cv2.waitkey(0) cv2.destroyAllWindows()由于我的测试图片太小了所以放大一些看import cv2 #图像地址 input_file rG:\Desktop\Image Processing\Test Dataset\test3.png #读取图像 image cv2.imread(input_file) #创建图像副本更改大小 display_image cv2.resize(image,None,fx1.5,fy1.5) #创建窗口 cv2.namedWindow(display_image,cv2.WINDOW_NORMAL) #显示图像 cv2.imshow(display_image,display_image) cv2.waitKey(0) cv2.destroyAllWindows()显示如下2.2 保存图像加上一行代码save_success cv2.imwrite(output_file, display_image)完整程序示例import cv2 #图像地址 input_file rG:\Desktop\Image Processing\Test Dataset\test3.png output_file rG:\Desktop\Image Processing\Test Dataset\test3_save.png #读取图像 image cv2.imread(input_file) #创建图像副本更改大小 display_image cv2.resize(image,None,fx1.5,fy1.5) #保存图片 save_success cv2.imwrite(output_file, display_image) #创建窗口 cv2.namedWindow(display_image,cv2.WINDOW_NORMAL) #显示图像 cv2.imshow(display_image,display_image) cv2.waitKey(0) cv2.destroyAllWindows()程序用法总结cv2.imwrite(output_file, display_image)output_file输出地址display_image需要保存的图像3 视频读取示例程序import cv2 #创建窗口 cv2.namedWindow(video,cv2.WINDOW_NORMAL) cv2.resizeWindow(video,600,800) #读取视频 cap cv2.VideoCapture(0) # 判断视频是否成功打开 if not cap.isOpened(): print(视频打开失败请检查文件路径) else: while True: # 读取一帧视频 ret, frame cap.read() # ret为False表示视频读取结束或读取失败 if not ret: print(视频播放结束) break # 显示当前帧 cv2.imshow(video, frame) # 每隔30毫秒检查一次键盘输入 # 按q键退出播放 if cv2.waitKey(30) 0xFF ord(q): break # 释放视频资源 cap.release() # 关闭所有窗口 cv2.destroyAllWindows()注意当cv2.VideoCapture(0)时表示调用的是你电脑上的摄像头也就是说当你用的是笔记本电脑的话就可以显示你的笔记本电脑的前置摄像头的画面非常好玩程序用法总结cap cv2.VideoCapture(video_file)打开指定路径的视频并创建一个视频读取对象cap。ret, frame cap.read()从视频中读取一帧返回两个结果。ret表示是否成功读取成功为True失败为Falseframe表示当前读取到的一帧图像本质上是一个 NumPy 数组。cv2.imshow(video, frame)把当前帧显示在窗口中。由于循环会不断读取新的一帧所以最终看起来就是视频。cap.release()视频读取结束后释放视频资源这是读取视频时必须养成的习惯。4 视频保存/录制示例程序import cv2 # 打开默认摄像头 cap cv2.VideoCapture(0) # 判断摄像头是否成功打开 if not cap.isOpened(): print(摄像头打开失败) exit() # 获取摄像头画面的宽度和高度 width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 设置录制帧率 fps 20 # 设置视频编码格式 fourcc cv2.VideoWriter_fourcc(*mp4v) # 设置输出视频地址 output_file rG:\Desktop\Image Processing\Test Dataset\record_video1.mp4 # 创建视频写入对象 writer cv2.VideoWriter( output_file, fourcc, fps, (width, height) ) # 判断视频写入对象是否创建成功 if not writer.isOpened(): print(视频保存对象创建失败) cap.release() exit() while True: # 读取摄像头的一帧 ret, frame cap.read() if not ret: print(画面读取失败) break # 将当前帧写入视频文件 writer.write(frame) # 显示当前画面 cv2.imshow(video, frame) # 按q键停止录制 if cv2.waitKey(1) 0xFF ord(q): break # 释放摄像头 cap.release() # 释放视频写入对象 writer.release() # 关闭所有窗口 cv2.destroyAllWindows() print(视频录制完成保存地址, output_file)程序用法总结writer cv2.VideoWriter(output_file,fourcc,fps,(width, height))创建视频写入对象它需要设置四项内容output_file视频的保存地址。fourcc视频编码格式。fps每秒保存多少帧。(width, height)保存视频的画面尺寸。writer.write(frame)负责把当前帧保存到视频中循环每运行一次就向视频文件中写入一帧。width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))可以看作三个函数首先是cap.get()对于cap来说是我们之前创建的视频读取对象cap cv2.VideoCapture(0),里面有图像的信息比如尺寸帧数等等。get()用于获取某项属性。cv2.CAP_PROP_FRAME_WIDTH表示获取每一帧画面的宽度。合起来就是我们最终的程序输入给width时转换为int型因为cap.get得到的是浮点型。5 图像的基本几何变换图像的几何变换是指改变图像中像素的空间位置从而实现缩放、裁剪、翻转、平移、旋转、倾斜和透视校正等效果。常见的几何变换包括图像缩放图像裁剪图像翻转图像平移图像旋转仿射变换透视变换这里介绍一下图像坐标系的原点是在左上角向右为X轴正方向向下为Y轴正方向。示例如下比如一个图像的尺寸是高20宽40那么示意图如下5.1 图像缩放示例程序import cv2 input_file rG:\Desktop\Image Processing\Test Dataset\test4.png #读取图像 image cv2.imread(input_file) #按固定尺寸缩放 display_image cv2.resize(image,(400,500)) #按比例缩放 display_image2 cv2.resize(image,None,fx0.5,fy0.5) cv2.imshow(image,image) cv2.imshow(display_image,display_image) cv2.imshow(display_image2,display_image2) cv2.waitKey(0) cv2.destroyAllWindows()结果原始图像按固定尺寸缩放按比例缩放程序用法总结这里用到的是之前使用过的函数cv2.resize()这里有两个用法 既可以设定固定尺寸也可以设定比例缩放。5.2 图像裁剪图像裁剪不需要使用专门的OpenCV函数可以直接通过NumPy数组切片完成。示例程序import cv2 import numpy as np input_file rG:\Desktop\Image Processing\Test Dataset\test4.png image cv2.imread(input_file) crop_image image[100:200,200:350] cv2.imshow(origin_image,image) cv2.imshow(crop_image2,crop_image) cv2.waitKey(0) cv2.destroyAllWindows()裁剪后的结果程序用法总结数组切片image[]用法为image[y1:y2,x1:x2]范围是前开后闭。比如程序中的image[100200,200:350]表示裁剪的低于为y轴方向的第100~199行x轴方向的第200~349行。5.3 图像翻转示例程序import cv2 import numpy as np input_file rG:\Desktop\Image Processing\Test Dataset\test4.png image cv2.imread(input_file) filp_image cv2.flip(image,1) cv2.imshow(origin_image,image) cv2.imshow(filp_image,filp_image) cv2.waitKey(0) cv2.destroyAllWindows()运行结果程序用法总结cv2.flip(image, flipCode)flipCode决定翻转方向。flipCode翻转方式1水平翻转即左右翻转0垂直翻转即上下翻转-1水平和垂直同时翻转5.4 图像旋转固定角度旋转示例程序import cv2 input_file rG:\Desktop\Image Processing\Test Dataset\test3.png image cv2.imread(input_file) # 顺时针旋转90° rotate_90_clockwise cv2.rotate( image, cv2.ROTATE_90_CLOCKWISE ) # 旋转180° rotate_180 cv2.rotate( image, cv2.ROTATE_180 ) # 逆时针旋转90° rotate_90_counterclockwise cv2.rotate( image, cv2.ROTATE_90_COUNTERCLOCKWISE ) cv2.imshow(Original Image, image) cv2.imshow(Rotate 90 Clockwise, rotate_90_clockwise) cv2.imshow(Rotate 180, rotate_180) cv2.imshow(Rotate 90 Counterclockwise, rotate_90_counterclockwise) cv2.waitKey(0) cv2.destroyAllWindows()结果程序用法总结cv2.rotate()固定角度旋转参数旋转方式cv2.ROTATE_90_CLOCKWISE顺时针旋转90°cv2.ROTATE_180旋转180°cv2.ROTATE_90_COUNTERCLOCKWISE逆时针旋转90°5.5 图像旋转任意角度旋转示例程序import cv2 import numpy as np input_file rG:\Desktop\Image Processing\Test Dataset\test4.png image cv2.imread(input_file) #高、宽 height,width image.shape[:2] #中心点 center (width//2,height//2) #旋转角度 angle 45 #缩放比例 scale 1.0 #创建旋转矩阵 rotation_matrix cv2.getRotationMatrix2D( center, angle, scale ) # 执行旋转 rotated_image cv2.warpAffine( image, rotation_matrix, (width, height) ) cv2.imshow(rotated_image,rotated_image) cv2.waitKey(0) cv2.destroyAllWindows()运行结果程序用法总结cv2.getRotationMatrix2D()旋转矩阵用法cv2.getRotationMatrix2D(center,angle,scale)其中 center代表旋转中心angle代表性旋转角度scale代表缩放比例。cv2.warpAffine()图像旋转操作5.6 图像平移图像平移就是将图像向上、下、左、右移动一定距离。示例程序import cv2 import numpy as np input_file rG:\Desktop\Image Processing\Test Dataset\test4.png image cv2.imread(input_file) #高、宽 height,width image.shape[:2] #设置平移距离 move_x 50 move_y 50 #创建旋转矩阵 move_matrix np.float32([ [1, 0, move_x], [0, 1, move_y] ]) move_image cv2.warpAffine(image,move_matrix,(width*2,height*2)) cv2.imshow(move_image,move_image) cv2.waitKey(0) cv2.destroyAllWindows()运行结果程序用法总结cv2.warpAffine()图像平移操作5.7 仿射变换仿射变换可以使图像发生平移旋转缩放倾斜拉伸我们之前的平移、旋转、缩放等都属于仿射变换。仿射变换前后原本平行的直线仍然保持平行。OpenCV通过三组对应点计算仿射变换矩阵cv2.getAffineTransform()然后使用cv2.warpAffine()完成图像变换。示例程序import cv2 import numpy as np input_file rG:\Desktop\Image Processing\Test Dataset\test3.png image cv2.imread(input_file) height, width image.shape[:2] # 原图中的三个点 source_points np.float32([ [0, 0], [width - 1, 0], [0, height - 1] ]) # 变换后三个点的位置 target_points np.float32([ [50, 50], [width - 100, 20], [100, height - 50] ]) # 计算仿射变换矩阵 affine_matrix cv2.getAffineTransform( source_points, target_points ) # 执行仿射变换 affine_image cv2.warpAffine( image, affine_matrix, (width, height) ) cv2.imshow(Original Image, image) cv2.imshow(Affine Image, affine_image) cv2.waitKey(0) cv2.destroyAllWindows()运行结果需要注意这三个点不能位于同一条直线上否则无法确定有效的仿射变换。程序用法总结affine_image cv2.warpAffine(image,affine_matrix,(width, height))image代表输入图像affine_matrix代表变换矩阵(width, height)表示显示窗口大小5.8 透视变换透视变换常用于文档矫正倾斜图像校正车道线检测将倾斜矩形变成正面矩形模拟近大远小的效果仿射变换需要三组对应点而透视变换需要四组对应点。透视变换使用cv2.getPerspectiveTransform()cv2.warpPerspective()示例程序import cv2 import numpy as np input_file rG:\Desktop\Image Processing\Test Dataset\test3.png image cv2.imread(input_file) height, width image.shape[:2] # 原图中的四个点 source_points np.float32([ [0, 0], [width - 1, 0], [0, height - 1], [width - 1, height - 1] ]) # 变换后的四个点 target_points np.float32([ [50, 50], [width - 100, 0], [0, height - 1], [width - 1, height - 50] ]) # 计算透视变换矩阵 perspective_matrix cv2.getPerspectiveTransform( source_points, target_points ) # 执行透视变换 perspective_image cv2.warpPerspective( image, perspective_matrix, (width, height) ) cv2.imshow(Original Image, image) cv2.imshow(Perspective Image, perspective_image) cv2.waitKey(0) cv2.destroyAllWindows()运行结果程序用法总结perspective_image cv2.warpPerspective(image,perspective_matrix,(width, height))image代表输入图像perspective_matrix代表变换矩阵(width, height)表示显示窗口大小6 常见问题宽度和高度顺序混淆使用shape时height, width image.shape[:2]使用resize()、warpAffine()和warpPerspective()设置输出尺寸时(width, height)也就是# shape先高度后宽度 height, width image.shape[:2] # OpenCV输出尺寸先宽度后高度 (width, height)7 总结几何变换主要方法图像缩放cv2.resize()图像裁剪NumPy数组切片图像翻转cv2.flip()固定角度旋转cv2.rotate()任意角度旋转cv2.getRotationMatrix2D()图像平移平移矩阵仿射变换cv2.getAffineTransform()透视变换cv2.getPerspectiveTransform()应用仿射矩阵cv2.warpAffine()应用透视矩阵cv2.warpPerspective()保存结果cv2.imwrite()其中平移、旋转、缩放和倾斜都可以归入仿射变换。它们的共同特点是先获得一个变换矩阵再将变换矩阵应用到图像上。