opencv-python图形图像处理入门基础知识

2023-11-10

☞ ░ 前往老猿Python博文目录

OpenCV 是计算机视觉中经典的专用库,其支持多语言、跨平台,功能强大。OpenCV-Python为OpenCV提供了Python接口,使得使用者在Python中能够调用C/C++,在保证易读性和运行效率的前提下,实现所需的功能。

一、安装

安装方法有多种,老猿机器上无C++环境,因此直接使用pip安装,OpenCV-Python模块名为opencv-python(在windows下大小写不敏感,其他操作系统没验证),具体安装命令如下:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

二、加载OpenCV

导入OpenCV 模块指令很简单:
import cv2 as cv

大多数OpenCV 的函数都在cv2模块内,cv2并不是版本2.X的意思,而是因为这个版本是在原cv版本的基础上采用了面向对象编程的方式重新实现,提供了更好的API接口。

三、读取图像文件

3.1、语法:imread(filename,mode)
3.2、参数说明
  • filename:图像文件名,不同操作系统支撑的文件类型不一样,但都支持bmp图像文件,另外可能还包括jpeg、png、tiff等格式文件
  • mode:文件读入模式,常用有三种取值
  1. cv.IMREAD_COLOR: 对应值为1,加载彩色图像。任何图像的透明度都会被忽视。它是默认标志。
  2. cv.IMREAD_GRAYSCALE:对应值为0,以灰度模式加载图
  3. cv.IMREAD_UNCHANGED:对应值为-1,加载图像,包括alpha通道

注意:除了这三个常用取值,还可以有多个取值,相关取值及含义如下:
在这里插入图片描述

3.3 返回值说明

imread返回一个BGR格式的图像对象,其类型为一个numpy数组。

3.4、案例
img = cv2.imread(r'F:\screenpic\redflower.jpg')
注意:
  1. 图片文件名不能是中文名,否则识别会报错或不能读入;
  2. imread会去除图像的alpha通道信息

四、显示图像

4.1、调用语法:imshow(title,img)
4.2、参数说明:
  • title:图像显示窗窗口标题和名字
  • img:opencv图像对象

imread读入的图像使用imshow即可显示,显示可以给显示窗设定标题,这个标题也是显示窗口的名字,标题不同的imshow会显示不同窗口。标题为一个英文字符串,相同标题的窗口就是同一个窗口。对于窗口,OpenCV提供鼠标及键盘事件处理机制。

imshow的窗口可以通过destroyWindow和destroyAllWindows进行关闭,前者要带窗口的标题,后者是关闭所有由当前程序创建的窗口。

4.3、案例
img = cv2.imread(r'F:\screenpic\redflower.jpg')
cv2.imshow('img',img)

五、VideoCapture读取摄像头、图像文件、或视频流

VideoCapture既支持从视频文件(.avi , .mpg格式)读取,也支持直接从摄像机(比如电脑自带摄像头)中读取。VideoCapture是一个类,要想获取视频需要先创建一个VideoCapture对象,VideoCapture对象的创建方式有以下三种:

调用语法:
  • VideoCapture(int deviceIndex,int apiPreference = CAP_ANY):打开摄像头捕获视频。deviceIndex为摄像头序列号,打开缺省摄像头传0,apiPreference 为VideoCapture API后端标识符,老猿没有仔细研究,用缺省值即可
  • VideoCapture(filename,int apiPreference = CAP_ANY)`:打开filename指定的文件
  • VideoCapture():创建一个对象,但没有确认捕获数据来源,需要通过VideoCapture其他方法来确认捕获数据来源

更多VideoCapture的内容请参考《opencv学习—VideoCapture 类基础知识》。

下面的代码打开缺省摄像头捕获视频,并将捕获内容显示为窗口视频,并写入视频文件中保存,按q终止退出:

import cv2 

def captureVideoFromCamera():
    cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
    WIDTH = 1920
    HEIGHT = 1920
    FILENAME = r'f:\video\myvideo.avi'

    FPS = 24
    cap.set(cv2.CAP_PROP_FPS, 24)
    # 建议使用XVID编码,图像质量和文件大小比较都兼顾的方案
    fourcc = cv2.VideoWriter_fourcc(*'XVID')

    out = cv2.VideoWriter(FILENAME, fourcc=fourcc, fps=FPS,frameSize=(WIDTH,HEIGHT))

    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    while True:
        # 逐帧捕获
        ret, frame = cap.read()
        # 如果正确读取帧,ret为True
        if not ret:
            print("Can't receive frame (stream end?). Exiting ...")
            break
        frame = cv2.flip(frame, 1)  # 水平翻转
        ret = out.write(frame)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 显示结果帧e
        cv2.imshow('frame', frame)
        if cv2.waitKey(1) == ord('q'):  break
    # 完成所有操作后,释放捕获器
    out.release()
    cap.release()
    cv2.destroyAllWindows()

captureVideoFromCamera()

六、OpenCV-Python的鼠标事件捕获

OpenCV提供了设置鼠标事件回调函数来提供鼠标事件处理的机制,设置回调函数的方法如下:
cv2.setMouseCallback(winName, OnMouseFunction, param)
其中winName为要设置鼠标回调处理的窗口名,OnMouseFunction为回调函数,用于处理鼠标响应,param为设置回调函数时传入的应用相关特定参数,可以不设置,但需要在回调函数访问设置回调函数对象属性时非常有用。

示例:

cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

七、waitKey键盘事件处理

openCV提供了快速的键盘处理支持函数waitKey,调用语法:
retval = cv.waitKey( [, delay] )
其中:

  • delay:等待键盘响应的时间,单位是毫秒,如果为0,则是一直等待到有键盘输入,否则就是等待对应时间还没有输入就超时返回
  • retval:如果是超时返回-1,否则返回对应键盘按键的ASCII码,但注意对于部分功能键如F1–F10返回值为0,其他功能键老猿未一一测试,可以确认ESC键值可以正常返回(返回值27),Ctrl+c返回3

八、OpenCV的矩形绘制

OpenCV提供了在图像中绘制几何图形的方法,绘制的图像包括矩形、椭圆、扇形、弧等。本文主要介绍矩形的绘制,具体调用语法如下:

rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)

其中参数:

  • img:要显示的图像,为numpy数组,格式为BGR格式
  • pt1:左上角点的坐标
  • pt2:右下角点的坐标
  • color:绘制的颜色,为BGR格式的三元组,如(255,0,0)表示蓝色
  • thickness:边框的厚度,如果为负数,则该矩形为实心矩形,否则为空心矩形
  • linetype:线型,包括4连通、8连通以及抗锯齿线型,使用缺省值即可
  • shift:坐标值的精度,为2就表示精确到小数点后2位

另外该方法还有个变种调用方式:
rectangle(img, rec, color[, thickness[, lineType[, shift]]]),其中的rec为上面pt1和pt2构建的矩形。

除了矩形,OpenCV还支持绘制点、直线、圆、椭圆、文本(不支持中文)等,具体可参考《使用Python OpenCV处理图像之详解直线、圆、矩形及文字的绘制》,老猿就不展开介绍了。

下面的示例代码是打开视频播放,鼠标点击后暂停播放并在点击位置画圆,再次点击恢复播放:

import cv2

def mouseEvent( event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        param[0] = not param[0]
        param[1] = (x,y)

def playVideoFile():
    cap = cv2.VideoCapture(r'f:\video\zbl1.mp4')
    fps = 1
    eventInf = [False,None]
    frame = None
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    cv2.namedWindow('image')
    cv2.setMouseCallback('image', mouseEvent,eventInf)
    while True:
        # 逐帧捕获
        pause,mousePos = eventInf
        if not pause:
            ret, frame = cap.read()
            if not ret:
                if frame is None :
                    print("The video has end.")
                else:
                    print("Read video error!")
                break

        else:
            if mousePos:
                cv2.circle(frame, mousePos,60,  (255,0,0),2)
        cv2.imshow('image', frame)
        ch = cv2.waitKey(int(1000/fps))
        if  ch == ord('q'):  break
    cap.release()
    cv2.destroyAllWindows()

playVideoFile()

九、OpenCV的颜色空间转换方法

cv2.cvtColor是openCV提供的颜色空间转换函数,调用语法如下:
cvtColor(src, code, dstCn=None)
其中:

  • src:要转换的图像
  • code:转换代码,表示从何种类型的图像转换为何种类型,如下面需要使用的cv2.COLOR_BGR2GRAY就是将BGR格式彩色图像转换成灰度图片,具体转换代码请参考官网文档
  • dstCn:目标图像的通道数,如果为0表示根据源图像通道数以及转换代码自动确认

更多内容请参考《学习opencv之cvtColor》,示例请参考下面图像阈值处理部分的案例。

十、图像阈值处理

openCV图像的阈值处理又称为二值化,之所以称为二值化,是它可以将一幅图转换为感兴趣的部分(前景)和不感兴趣的部分(背景)。转换时,通常将某个值(即阈值)当作区分处理的标准,通常将超过阈值的像素作为前景。

阈值处理有2种方式,一种是固定阈值方式,又包括多种处理模式,另一种是非固定阈值,由程序根据算法以及给出的最大阈值计算图像合适的阈值,再用这个阈值进行二值化处理,非固定阈值处理时需要在固定阈值处理基础上叠加组合标记。

调用语法:
retval, dst = cv2.threshold (src, thresh, maxval, type)
其中:

  • src:源图像,8位或32位图像的numpy数组
  • thresh:阈值,0-255之间的数字,在进行处理时以阈值为边界来设不同的输出
  • maxval:最大阈值,当使用固定阈值方法时为指定阈值,当叠加标记时为允许最大的阈值,算法必须在小于该值范围内计算合适的阈值
  • type:处理方式,具体取值及含义如下:
    在这里插入图片描述
  • dst:阈值化处理后的结果图像numpy数组,其大小和通道数与源图像相同
  • retval:叠加cv2.THRESH_OTSU或cv2.THRESH_TRIANGLE标记后返回真正使用的阈值

案例:

ret, mask = cv2.threshold(img, 35, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)

补充说明:

  1. 阈值判断时,是以小于等于阈值和大于阈值作为分界条件
  2. 如果是32位彩色图像,则是以RGB每个通道的值单独与阈值进行比较,按每个通道进行阈值处理,返回的是一个阈值处理后的RGB各自的值。请参考《OpenCV阈值处理函数threshold处理32位彩色图像的案例》。

下面的代码生成一个图像的掩码图像:

def createImgMask(img):
    # 创建img的掩码
    if img is None:return None
    if len(img.shape)>=3:
        img2gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    else:img2gray = img
    ret, mask = cv2.threshold(img2gray, 35, 255, cv2.THRESH_BINARY)

    return mask

十一、adaptiveThreshold自适应阈值化图像处理

上面介绍的threshold 函数的图像阈值处理对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力。图像阈值化操作中,我们更关心的是从二值化图像中分离目标区域和背景区域,仅仅通过固定阈值很难达到理想的分割效果。在图片中的灰度是不均匀的,所以通常情况下图片中不同区域的阈值是不一样的。这样就需要一种方法根据图像不同区域亮度或灰度分布,计算其局部阈值来进行阈值处理。这种方法就是自适应阈值化图像处理,实际上这可以称为局部阈值法,在OpenCV中的adaptiveThreshold就是这种方法。

调用语法:
adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)

说明:

  • src:源图像,必须是8位的灰度图
  • dst:处理后的目标图像,大小和类型与源图像相同
  • maxValue:用于指定满足条件的像素设定的灰度值
  • adaptiveMethod:使用的自适应阈值算法,有2种类型ADAPTIVE_THRESH_MEAN_C算法(局部邻域块均值)或ADAPTIVE_THRESH_GAUSSIAN_C(局部邻域块高斯加权和),ADAPTIVE_THRESH_MEAN_C的计算方法是计算出邻域的平均值再减去第六个参数C的值,ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出邻域的高斯均匀值再减去第六个参数C的值。处理边界时使用BORDER_REPLICATE | BORDER_ISOLATED模式
  • thresholdType:阈值类型,只能是THRESH_BINARY或THRESH_BINARY_INV二者之一,具体参考上面“图像阈值处理”的表格
  • blockSize:表示邻域块大小,用来计算区域阈值,一般选择3、5、7……
  • C:表示常数,它是一个从均匀或加权均值提取的常数,通常为正数,但也可以是负数或零
  • 返回值:处理后的图像

补充说明:

  1. 亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小
  2. 在灰度图像中,灰度值变化明显的区域往往是物体的轮廓,所以将图像分成一小块一小块的去计算阈值往往会得出图像的轮廓。因此函数adaptiveThreshold除了将灰度图像二值化,也可以进行边缘提取
  3. 之所以能进行边缘提取,是因为当block很小时,如block_size=3 or 5 or 7时,“自适应”的程度很高,即容易出现block里面的像素值都差不多,这样便无法二值化,而只能在边缘等梯度大的地方实现二值化,结果显得它是边缘提取函数
  4. 当把blockSize设为比较大的值时,如blockSize=21 or 31 or 41时,adaptiveThreshold便是二值化函数
  5. blockSize必须为大于1的奇数(原理老猿还没弄清楚) ,
  6. 如果使用平均值方法,平均值mean为180,差值delta为10,maxValue设为255。那么灰度小于170的像素为0,大于等于170的像素为255,如果是反向二值化,灰度小于170的像素为255,大于等于170的像素为0

案例:

import cv2

img = cv2.imread(r'F:\screenpic\1.jpg',cv2.IMREAD_GRAYSCALE)
newImg = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 3, 5)
cv2.imshow('img',img)
cv2.imshow('newImg',newImg)
cv2.waitKey(60000)

运行效果:
源图:
在这里插入图片描述
下面是分别设置不同块大小的结果图,左图块大小为31,右图为3:
在这里插入图片描述
可以看到blockSize小时,轮廓识别效果明显,而大时,就是一个二值化图像。

十二、OpenCV的图像修复方法

OpenCV中的cv2.inpaint()函数使用插值方法修复图像,调用语法如下:
dst = cv2.inpaint(src,mask, inpaintRadius,flags)

参数含义如下:

  • src:输入8位1通道或3通道图像
  • inpaintMask:修复掩码,8位1通道图像。非零像素表示需要修复的区域
  • dst:输出与src具有相同大小和类型的图像
  • inpaintRadius:算法考虑的每个点的圆形邻域的半径
  • flags:修复算法标记,其中INPAINT_NS表示基于Navier-Stokes方法,INPAINT_TELEA表示Alexandru Telea方法。具体方法在此不展开介绍

下面的代码对一个包含亮色Logo的图片进行去Logo处理:

import cv2


def createImgMask(img):
    # 创建img的掩码
    if img is None:return None
    if len(img.shape)>=3:
        img2gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    else:
        img2gray = img
    ret, mask = cv2.threshold(img2gray, 35, 255, cv2.THRESH_BINARY)

    return mask

def delLogFromImg(img):
    imgMask = createImgMask(img)
    imgMask = cv2.inpaint(img, imgMask , 3, cv2.INPAINT_TELEA)
    return imgMask

img1 = cv2.imread(r'F:\temp\logo.jpg')
img2 = cv2.imread(r'F:\temp\logo.jpg',cv2.IMREAD_GRAYSCALE)

newImg1 = delLogFromImg(img1)
newImg2 = delLogFromImg(img2)

cv2.imshow('img1',img1)
cv2.imshow('newImg1',newImg1)

cv2.imshow('img2',img2)
cv2.imshow('newImg2',newImg2)
cv2.waitKey(60000)

执行截图1:
在这里插入图片描述

小结

本文详细介绍了opencv-python的安装、加载图像文件、捕获摄像头、显示图像、鼠标事件捕获、键盘事件处理、几何图像绘制、颜色空间转换、图像阈值处理、图像修复等基础知识,适合开始学习opencv-python的初学者。

关于老猿的付费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深入、案例更多。

付费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》。

关于Moviepy音视频开发的内容,请大家参考《Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载》的导览式介绍。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python!

☞ ░ 前往老猿Python博文目录

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv-python图形图像处理入门基础知识 的相关文章

随机推荐

  • 02-express安装apidoc生成接口文档

    02 express安装apidoc生成接口文档 1 安装 npm i apidoc 2 在项目根目录下创建 apidoc json name news是项目接口文档 version 0 1 0 description 新闻接口文档 tit
  • SpringCloud之Feign传递Json参数(个人使用)

    SpringCloud之Feign传递Json参数 个人使用 Client端 启动类 SpringBootApplication EnableDiscoveryClient EnableFeignClientspublic class Fe
  • 条款11:优先选用删除函数,而非private 未定义函数

    使用场景 比如在自定义类中 为了阻止其他程序员使用 拷贝构造 等函数 我们常用的用法 将该函数定义为private 不去定义只是声明 或者delete 区别 区别一 delete 可以修饰任何函数 private 只能修饰类 类对象 的成员
  • myeclipse java错误提示_myeclipse常见错误集锦 及解决方案

    1 An internal error occurred during Add Deployment Container with path org eclipse jdt launching JRE CONTAINER org eclip
  • vcxsrv连linux黑屏,通过 VcXsrv 在 WSL2 上使用图形化界面(xfce4)

    当然网络上已经有很多相关教程了 但是对于我的情况那些方法都不完全正确以至于我不能使用图形化界面 所以如果你查了很多方法也不能使用的话可以看看这篇 这是我的系统参数 开门见山 启动 VcXsrv 在 Windows 上下载 VcXsrv 并安
  • 词向量实践(gensim)

    词向量训练步骤 分词并去停用词 词频过滤 训练 项目完整地址 https github com cyandn practice tree master Word2Vec gensim中Word2Vec参数解释 主要参数介绍如下 senten
  • 基于Matlab的变压器铁芯截面优化设计

    基于Matlab的变压器铁芯截面优化设计 前言 优化思路 Matlab程序运行结果 结果分析 代码 前言 变压器是电力系统中非常重要的设备 在变压器设计过程中 给定的铁心直径条件下 铁心截面积越大 填充率越高 变压器经济指标越好 因此铁心截
  • WIN10 编译ffmpeg(包含ffplay)

    1 安装MSYS2 Win10 搭建MSYS2环境 cloud yq的博客 CSDN博客 2 编译SDL SDL是编译生成ffplay的基础 不需要生成ffplay可不编译SDL 1 下载地址 https www libsdl org do
  • Mall谷粒商城(基础篇的开发)

    项目简介 Mall商城项目致力于打造一个完整的大型分布式架构的电商平台 采用先阶段流行的前后端分离模式编写 Mall商城是一套电商项目 包括前台的商城系统以及后台管理系统 基于SpringCloud SpringCloud Alibaba
  • 基于51单片机的HX711模块

    一 项目介绍 基于51单片机的HX711称重计 最大称重量为5kg 并且在LCD1602上显示数值 可设置称重物品单价 称重精度可由按键key调节 误差可达0 传感器在某宝上买的 需要可以找我拿连接 二 HX711简介 HX711是一款专为
  • Database returned an invalid datetime value. Are time zone definitions for your database installed?

    Django gt python manage py runserver时报错 Database returned an invalid datetime value Are time zone definitions for your d
  • GCC编译选项参数介绍

    gcc和g 分别是gnu的c和c 编译器 下面是整理的常用编译选项参数 1 x 设定文件所使用的语言 使文件后缀名无效 如下 执行完后生成test o gcc c x c test jpg 2 c 只编译生成目标文件即 o 只编译不链接生成
  • Spring Boot通过lombok提供的Slf4j省略日志的创建操作

    上文 Spring Boot将声明日志步骤抽离出来做一个复用类中 我们写了个创建日志的公开类 但这么简单的东西 自然有人会将它写好 lombok已经 提供出了这个工具 首先 我们需要在 pom xml 中加上这样一段代码
  • NB-IOT/Lora/Zigbee/WIFI/蓝牙无线组网方式的对比

    NB IOT Lora Zigbee WIFI 蓝牙无线组网方式的对比 LoRa LoRa 长 距离 是由Semtech公司开发的一种技术 典型工作频率在美国是915MHz 在欧洲是868MHz 在亚洲是433MHz LoRa的物理层 PH
  • 互联网摸鱼日报(2023-09-12)

    互联网摸鱼日报 2023 09 12 36氪新闻 东方树叶 被中年男人买疯了 马斯克重申 特斯拉将取消 实体后视镜 一封钓鱼电邮背后的AI攻防战 苹果iPhone 15系列预测分析 哪些靠谱 该选哪个版本 纯电版丰田埃尔法 难以重现燃油版的
  • PMOS 型的 LDO

    在前面讲 NMOS LDO 的时候 我们注意到 NMOS 由于它的源极和门级之间的导通门限 使 简单构成的 NMOS LDO 它输入和输出之间的压差不可能很小 必须大于这个导通门限 如果 我们引入一个单个的偏置电压对某些应用又是一个负担 因
  • Ag-grid表格 原生javascript的简单使用

    ag grid是支持多种前端框架的企业级表格框架 它能实现的功能也颇多 有兴趣的可以上他的官网api看下ag Grid官网 我这里简单写一下基础的数据初始化生成表格 1 首先引入js文件 我这里用原生的方式 并没有使用vue之类的框架的方法
  • go 进阶 https与http2

    目录 一 复习 https 与 http2 https 是什么 https 原理是什么 http 与https的区别 http2 与http1 x区别 二 golang https http2 基础示例 httputil ReversePr
  • API接口:企业信息核验

    企业信息核验是现代企业管理中必不可少的一项业务 它可以帮助企业做出正确的决策 在这篇文章里 我们将会介绍如何使用API接口来对企业信息进行核验 并实现快捷 准确的查询 一 API接口 在这里我们使用的是挖数据提供的企业信息核验API接口 它
  • opencv-python图形图像处理入门基础知识

    前往老猿Python博文目录 OpenCV 是计算机视觉中经典的专用库 其支持多语言 跨平台 功能强大 OpenCV Python为OpenCV提供了Python接口 使得使用者在Python中能够调用C C 在保证易读性和运行效率的前提下