图像处理入门

之前我们已经讲过了OpenCV在各个平台上安装的方法了,从今天开始,正式进入实战部分。首先我们需要做的就是如何读取图像并显示出来,这是图像处理的最基本的部分。

首先我们来了解几个函数。

▼cv2.imread()

我们看一下函数的原型:

retval=cv.imread(filename[, flags])

retval为自定义名称,filename指代需要加载的文件名,一般情况下,大多数时候,我们是直接加载文件的,所以大多时候我们直接读入图像就可以,但是在一些时候,我们想直接将原图转化为灰度图,从而方便后期的形态学处理操作,那么这个时候第二个参数的意义就表现出来了,第二个参数属于一个标志,它用于指定读取图像的方式。

总共有三种方式:

  • cv.IMREAD_COLOR:加载彩色图像。图像的任何透明度都将被忽略。这是默认标志。

  • cv.IMREAD_GRAYSCALE:以灰度模式加载图像。

  • cv.IMREAD_UNCHANGED:加载图像,包括alpha通道。

当然了,为了方便起见,它们也可以分别用1,0,-1进行表示。1指代原图也就是第一个函数;0指代第二个函数代表转为灰度图;-1则为第三个函数。

▼cv2.imshow()

该函数用于在窗口中显示图像,窗口自动适合当前输入的图像尺寸,该函数与imread函数是相辅相成的,该函数原型为:

None=cv.imshow(winname, mat)

None为不需要填写,不用管它,我们直接用imshow就可以,winname是指你输出的图像的名称,可以自定义,但不要用中文名称,否则会乱码;mat则为你需要显示的图像。

此函数之后应是cv2.waitKey()函数,该函数显示指定毫秒的图像。如果不使用waitkey函数,它将不会显示图像。例如,waitKey(0)将无限期显示窗口,直到任何按键为止(适用于图像显示)。waitKey(25)将显示25毫秒的帧,此后将自动关闭显示。

另一个函数cv2.destroyAllWindows()会销毁我们创建的所有窗口。 如果要销毁任何特定的窗口,请使用函数 cv.destroyWindow()在其中传递确切的窗口名称作为参数。

我们现在来做一个实验,先显示最基本的图像(代码图中都有):

现在我们改变读入的图像为灰度,mread函数的最后一个参数可以进行相关方面的操作,当为0时:

当为1时:

若为-1时:

现在输出的图像的窗口大小是固定的,那么加入我们想要调整窗口的大小,那就需要使用另一个函数,在特殊情况下,我们可以创建一个空窗口,然后再将图像加载到该窗口。在这种情况下,可以指定窗口是否可调整大小。

这是通过功能cv.namedWindow()完成的,现在我们实验一下:

当我们在函数后加一个0,则可以用鼠标手动调整输出图像的大小,这将非常方便。事实上,0对应的参数为cv2.WINDOW_NORMAL,即为自动调整图像,我们大致了解一下相关的参数:

  • WINDOW_NORMAL

    或WINDOW_AUTOSIZE:

    WINDOW_NORMAL可以调整窗口大小,而WINDOW_AUTOSIZE会自动调整窗口大小以适合显示的图像(请参见imshow),并且不能手动更改窗口大小。

  • WINDOW_FREERATIO

    或WINDOW_KEEPRATIO:

    WINDOW_FREERATIO调整图像时不考虑其比例,而WINDOW_KEEPRATIO则保持图像比例。

  • WINDOW_GUI_NORMAL

    或WINDOW_GUI_EXPANDED:

    WINDOW_GUI_NORMAL是绘制没有状态栏和工具栏的窗口的旧方法,而WINDOW_GUI_EXPANDED是新的增强型GUI。默认标志==WINDOW_AUTOSIZE | WINDOW_KEEPRATIO | WINDOW_GUI_EXPANDED

假若我们想将处理之后的图像保存起来,保存到文件夹中,那么就需要用到cv2.imwrite函数。

▼cv2.imwrite()

imwrite函数将图像保存到指定文件。图像格式是根据文件扩展名选择的(扩展名列表请参见cv :: imread)。通常,使用此功能只能保存8位单通道或3通道(具有“ BGR”通道顺序)图像,但以下情况除外:

  • 对于PNG,JPEG 2000和TIFF格式,可以保存16位无符号(CV_16U)图像。

  • 可以以PFM,TIFF,OpenEXR和Radiance HDR格式保存32位浮点(CV_32F)图像;使用LogLuv高动态范围编码(每像素4个字节)将保存3通道(CV_32FC3)TIFF图像。

  • 使用此功能可以保存带有Alpha通道的PNG图像。为此,创建8位(或16位)4通道图像BGRA,其中alpha通道位于最后。完全透明的像素应将alpha设置为0,完全不透明的像素应将alpha设置为255/65535。

该函数原型为:

retval=cv.imwrite(filename, img[, params])

第一个参数是文件名,第二个参数是要保存的图像。现在我们写个综合代码:

import numpy as np

import cv2 as cv

img = cv.imread('cat.jpg', 0)

cv.imshow('image', img)

k = cv.waitKey(0) & 0xff

if k == 27:  # wait for ESC key to exit

    cv.destroyAllWindows()

elif k == ord('s'):  # wait for 's' key to save and exit

    cv.imwrite('cat.png', img)

    cv.destroyAllWindows()

在上面的程序中,以灰度加载图像,显示图像,按下键盘的“ s”键保存图像并退出,或者按ESC键直接退出而不保存。我们按下s实验:

图像保存完毕。

那么图像处理的入门部分算是正式结束了,这也是基础中的基础,后续都将非常有用。

视频处理入门

视频处理在OpenCV中处于极为重要的地位,目标实时跟踪等各种实时图像处理算法都是以视频为基础。

01

从相机捕获视频

首先我们来了解一下使用电脑自带的相机来进行捕获视频。通常,我们必须使用摄像机捕获实时流。OpenCV提供了一个非常简单的界面来执行此操作。让我们从相机捕获视频(我使用笔记本电脑上的内置网络摄像头),我们需要了解几个函数:

▼cap = cv2.VideoCapture(0)

VideoCapture()中参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频,如cap = cv2.VideoCapture("../test.avi"),当然了,如果你外接的有其他的摄像头,那就可以选用其他的参数例如1从而调用它。

▼ret,frame = cap.read()

cap.read()按帧读取视频,ret,frame是获取cap.read()方法的两个返回值。其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵,我们都知道视频是由一帧一帧的图像连续组成的,OpenCV在对图像处理时就是对每一帧的图像进行快速处理。

▼cv2.waitkey()

waitKey()方法本身表示等待键盘输入,参数是1,表示延时1ms切换到下一帧图像,对于视频而言;参数为0,如cv2.waitKey(0)只显示当前帧图像,相当于视频暂停,;参数过大如cv2.waitKey(1000),会因为延时过久而卡顿感觉到卡顿。

c得到的是键盘输入的ASCII码,esc键对应的ASCII码是27,即当按esc键是if条件句成立。

release()

调用release()释放摄像头,调用destroyAllWindows()关闭所有图像窗口。

现在我们首先进行代码实验,之后会进行一些说明:

import numpy as np

import cv2 as cv

cap = cv.VideoCapture(0)

if not cap.isOpened():

    print("Cannot open camera")

    exit()

while True:

    # Capture frame-by-frame

    ret, frame = cap.read()

    # if frame is read correctly ret is True

    if not ret:

        print("Can't receive frame (stream end?). Exiting ...")

        break

    # Our operations on the frame come here

    # gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

    # Display the resulting frame

    cv.imshow('frame', gray)

    if cv.waitKey(1) == ord('q'):

        break

# When everything done, release the capture

cap.release()

cv.destroyAllWindows()

isOpened可以确定摄像头是否被打开,如果打开则继续,如果未成功打开则自动退出。前面的时候我们已经讲过,frame所指代的,就是摄像头视频的每一帧图像,所以在显示时,我们也是显示每一帧。如果对每一帧图像都进行灰度化处理,那么所显示的视频就是灰度化视频,当然,关于灰度化现在还没有讲到,但是可以先做个小实验,我们来看代码:

import numpy as np

import cv2 as cv

cap = cv.VideoCapture(0)

if not cap.isOpened():

    print("Cannot open camera")

    exit()

while True:

    # Capture frame-by-frame

    ret, frame = cap.read()

    # if frame is read correctly ret is True

    if not ret:

        print("Can't receive frame (stream end?). Exiting ...")

        break

    # Our operations on the frame come here

    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

    # Display the resulting frame

    cv.imshow('frame', gray)

    if cv.waitKey(1) == ord('q'):

        break

# When everything done, release the capture

cap.release()

cv.destroyAllWindows()

大家自己实验,体验一下效果。或许有的人已经发现了,我们的视频跟实际中好像是相反的,属于镜像效果,我们可以取消这种效果,在这里需要介绍一个函数,后面在图像增强部分也会介绍到:

▼cv2.flip ()

函数原型:flip(src, flipCode[, dst])

src代表输入的图像,我们来看一下flipCode的参数表:

现在我们加入这行代码:

import numpy as np

import cv2 as cv

cap = cv.VideoCapture(0)

if not cap.isOpened():

    print("Cannot open camera")

    exit()

while True:

    # Capture frame-by-frame

    ret, frame = cap.read()

    frame = cv.flip(frame, 1)

    # if frame is read correctly ret is True

    if not ret:

        print("Can't receive frame (stream end?). Exiting ...")

        break

    # Our operations on the frame come here

    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

    # Display the resulting frame

    cv.imshow('frame', gray)

    if cv.waitKey(1) == ord('q'):

        break

# When everything done, release the capture

cap.release()

cv.destroyAllWindows()

再实验会发现图像已经没有那种镜像效果了。

02

从文件播放视频

从文件播放视频与从摄像机捕获视频相同,只是将摄像机索引更改为视频文件名。另外,在显示框架时,请使用适当的时间cv.waitKey()。如果太少,则视频将非常快,而如果太高,则视频将变得很慢(嗯,这就是显示慢动作的方式)。正常情况下25毫秒就可以了。

给出实例代码:

import cv2 as cv

cap = cv.VideoCapture('test.avi')

while cap.isOpened():

    ret, frame = cap.read()

    # if frame is read correctly ret is True

    if not ret:

        print("Can't receive frame (stream end?). Exiting ...")

        break

    cv.imshow('frame', frame)

    if cv.waitKey(25) == ord('q'):

        break

cap.release()

cv.destroyAllWindows()

03

保存视频

当我们想要保存图像的时候,这非常简单:只需使用cv2.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')or cv.VideoWriter_fourcc(*'MJPG')`传递。

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

import numpy as np

import cv2 as cv

cap = cv.VideoCapture(0)

# Define the codec and create VideoWriter object

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, 1)

    # write the flipped frame

    out.write(frame)

    cv.imshow('frame', frame)

    if cv.waitKey(1) == ord('q'):

        break

# Release everything if job is finished

cap.release()

out.release()

cv.destroyAllWindows()

大家可以自己尝试演示效果。

视频处理的部分基本上就结束了,以上介绍到的将是以后学习中非常重要的基础。而事实上,OpenCV中对于视频的处理也有更多的操作,现在介绍最后一个函数:

▼VideoCapture.get()

由于前面我们已经指定cap = cv.VideoCapture(0),所以调用此函数只需用cap.get(),get中将传入参数,给出参数表:

共有18个参数,而至于相关的代码,请大家自己实验,可以使用print函数输出视频的详细信息。

扫码入群扫码添加管理员微信

加入“电子产品世界”粉丝交流群

↓↓↓↓点击,查看更多新闻

opencv mat release thrown_【OpenCV+Python】图像与视频处理入门相关推荐

  1. 【OpenCV 4开发详解】图像与视频的保存

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  2. python 图像和视频互相转换

    python 图像和视频互相转换 预备条件 视频转图像 图像转视频 完整代码 预备条件 创建两个文件夹,将视频放在video文件夹里 我拍的视频,视频链接 提取码:t1zj 视频转图像 import ...

  3. OpenCV可移植图形工具HighGUI实现图像和视频操作

    OpenCV把用于操作系统.文件系统以及摄像机等硬件设备交换的函数纳入了HighGUI(High-level Graphical User Interface)模块中.有了HighGUI模块,我们可以 ...

  4. opencv mat 修改_C++ opencv矩阵和pytorch tensor的互相转换

    矩阵和tensor相互转换 cvmat到tensor tips:这里主要要注意的就是在opencv和pytorch中存储顺序的差异 cv::cvtColor(frame, frame, CV_BGR2 ...

  5. 【OpenCV 4开发详解】图像二值化

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. 【OpenCV 4开发详解】图像噪声的种类与生成

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  7. 【OpenCV 4开发详解】图像卷积

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  8. 【OpenCV 4开发详解】图像直方图绘制

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  9. 【OpenCV 4开发详解】图像金字塔

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

最新文章

  1. 【OpenCV的C++教程3】掩膜操作的细节
  2. 皮尔逊相关系数 定义+python代码实现 (与王印讨论公式)
  3. python函数变量的作用域_学不会的Python函数——变量作用域
  4. Wi-Fi 协议和数率?
  5. 关于Scalability的一些思考与疑问
  6. 64位树莓派运行linux,树莓派3B+安装64位debian GUN/Linux系统
  7. 一种结合颜色特征和区域生长的疾病斑图像分割方法(复杂环境下分割效果好)
  8. 斗地主实现洗牌发牌功能
  9. GitHub 和GitLab的开发工具使用
  10. 《数据分析思维手册》和《数据分析师的职场真相》全集整理好啦,下载保存!...
  11. python控制安捷伦频谱仪_安捷伦频谱仪使用说明
  12. Appium:ios自动化环境搭建
  13. Linux命令大全(超详细版)
  14. SDL游戏之路(十一)--按钮制作
  15. Web调用海康威视摄像头
  16. 宋朝历史衰败原因大揭秘
  17. M2M技术的基本框架
  18. Tomcat多实例Nginx负载均衡
  19. 为什么宝宝做错事被骂哭后,还要求抱抱?
  20. 原来你叫“派森”(一)

热门文章

  1. 对软件测试的理解(英文)
  2. flutter 自定义 AppBar
  3. C#语言和SQL Server 数据库处理
  4. 关于mount在unix系统上
  5. nagios errors
  6. 【精解】Exchange Server 2007群集连续复制
  7. Linux颜色所代表的文件类型
  8. Web前端_项目实践01_萌娃摄影网页(纯HTML+CSS静态页面)
  9. leetcode 遇到的问题
  10. sonarqube通过sonarqube maven插件分析maven工程使用的mvn命令示例