openCV入门学习基础教程第一篇

目录
  • 前言:计算机眼中的图片
  • 1. 图片的读取与显示
    • 1.1 图片的读取
    • 1.2 显示的图片
      • 1.2.1 显示原始图片
      • 1.2.2 灰度图
    • 1.3 BGR转换成灰度图、RGB
  • 2. 保存图片
  • 3. 视频的读取与显示
  • 4. 截取图像部分
  • 5. 颜色通道提取
  • 6. 边界填充
  • 7. 数值计算
  • 8. 图像融合
  • 9. 知识点总结*
  • 总结

前言:计算机眼中的图片

  • 计算机中图片由许多个像素点组成,如一个500x500的图片,表示长宽各由500个像素点组成。
  • 计算机中一个像素点的值在0-255表示该点亮度  0暗(黑)-255亮(白)
  • 一张彩图通常是由RGB(red、green、blue)三个颜色通道所组成
  • 一个500x500的图片那他们的 RGB 矩阵也各是500x500。

上图我们将一个大的图片分割成许多如20x20的小图片,同理每个小图片它们的RGB矩阵也各自是20x20。

注:opencv默认顺序不是RBG 而是 BGR。

1. 图片的读取与显示

1.1 图片的读取

import cv2
img = cv2.imread('./data/abv.jpg')

img = cv2.imread('./data/abv.jpg') 

比如我读入这样一张图片,命名为img

我们可以看到img是一个三维ndarray结构,内部数据类型dtype=unit8:

三维:(1080,1920,3)表示高度、宽度、颜色通道个数(cv彩图BGR)ndarray结构:数据类型dtype=unit8, 0-255。

1.2 显示的图片

1.2.1 显示原始图片

cv2.imshow('image',img) # 第一个参数表示窗口指定的名字 第二个为上方img
cv2.waitKey(5000) # 等待时间  如果是5000则在5s后图片窗口自动关闭  0表示任意键关闭
cv2.destroyAllWindows() # 时间一到关闭窗口

ps: 图像的显示也可以是多个窗口

  • cv2.imshow('image',img) 自己给将要弹出的窗口起个名  再加入变量img
  • cv2.waitKey(5000) 等待时间  如果是5000则在5s后图片窗口自动关闭  0表示任意键关闭
  • cv2.destroyAllWindows() 时间一到关闭窗口

为方便下面使用,我们自己定义一个函数cv_show():

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

执行代码,弹出窗口,显示图片:

cv_show('winName',img)

1.2.2 灰度图

在之前的基础之上加入参数:cv2.IMREAD_GRAYSCALE

img2=cv2.imread('./data/abv.jpg',cv2.IMREAD_GRAYSCALE)  # cv2.IMREAD_COLOR

img2=cv2.imread('./data/abv.jpg',cv2.IMREAD_GRAYSCALE)

  • cv2.IMREAD_GRAYSCALE  读取为灰度图,也可以写0。
  • cv2.IMREAD_COLOR           读取为彩图

我们执行:

cv_show('win2',img2) 

可以看到该图片最终显示结果为二维(1080,1920) :

ps: img.size 输出像素点的个数,可以看到同一张图片BGR彩图是灰度图的三倍。

1.3 BGR转换成灰度图、RGB

当然我们也可以把已经读取进来的BGR彩图转换成灰度图,或者转换为RGB。

img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv_show('win3',img2)

img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 

  • cv2.COLOR_BGR2RGB 将BGR格式转换成RGB
  • cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片

2. 保存图片

cv2.imwrite('./data/grayPhoto.jpg',img2)

cv2.imwrite('./data/grayPhoto.jpg',img2)

此时我的data文件夹下就多了一张才处理好名为grayPhoto的灰度图。

3. 视频的读取与显示

视频也是由图像组成的,每一帧都可以当作是一个静止的图像,把图像连在一起看着就像是一个视频了。 我们打游戏时,也是追求一些更高的帧率。

vc = cv2.VideoCapture('./data/stu.mp4')

vc = cv2.VideoCapture('./data/stu.mp4')

# 检查是否正确打开
if vc.isOpened():
    open,frame = vc.read()
else:
    open = Flase

vc.read()

  • 读取视频中的第一帧 ,再次执行vc.read()的话读取视频第二帧
  • 返回值中:第一个:布尔类型,能读进来就是True   第二个像是上面的img,这一帧图片的ndarray矩阵

循环图片播放视频:

while open:
    ret,frame = vc.read()
    if frame is None:
        break
    if ret == True:
        # 原本frame是(h,w,3)的BGR图片矩阵 经下方加入参数转换成黑白gray
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        cv2.imshow('result',gray)
        # cv2.waitKey(num) 该图片显示时间/速度 自己可以找一个合适的值
        # 27指退出键ESC 退出窗口  当然也可以是 =='q'等
        if cv2.waitKey(20)&0xFF == 27:
            break
vc.release()
cv2.destroyAllWindows()

注:视频放完 ret, frame = vc.read()返回False和None 再次进行循环无法播放视频,需要重新读取。

if cv2.waitKey(20)&0xFF == 27:

  • 不是新知识点了,表示每张图片等20毫秒,如果按ESC键直接退出。

4. 截取图像部分

我们上面介绍,img是一个ndarray矩阵,因此对其进行切片操作:

pho = img[100:800,200:800]  # 进行切片 高100到800 宽200到800
cv_show('win2',pho)

pho = img[100:800,200:800]

5. 颜色通道提取

b,g,r = cv2.split(img)
# b.shape g.shape r.shape 都为 (1080, 1920)

执行

cv_show('win3',g) # 或者填 b、r

结果就是单通道图。

如果我们想显示单一颜色,如红色:

cur_img = img.copy()
cur_img[:,:,0] = 0 # B不要了 设置为0
cur_img[:,:,1] = 0 # G不要了 设置为0
#cur_img[:,:,2] = 0 # R不要了 设置为0
cv_show('winR',cur_img)

6. 边界填充

这个一般用于卷积,在图像周围填充一些像素。

我们以这个图片为例:

img = cv2.imread('./data/gd01.jpg')
# img.shape 为 (300, 400, 3)
cv_show('win1',img)

在图片的上下左右填充50个像素,介绍5种方法:

top_size,bottom_size,left_size,right_size=(50,50,50,50)

# 不同的填充方法 最后参数改个type值就行
replicate = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT)
reflect101=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_CONSTANT,value=0)
plt.subplot(231),plt.imshow(img,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
# 注matplotlib默认R G B本例只介绍边界填充
plt.show()

  • cv2.BORDER_REPLICATE

    • 复制最边缘的像素
  • cv2.BORDER_REFLECT
    • 反射法对感兴趣的图像中的像素在两边进行复制 如fedcba|abcdefgh|hgfedcb 其中abcdefgh是图像"|"外的是填充内容
  • cv2.BORDER_REFLECT_101
    • 反射法,也就是以最边缘的像素为轴,对称,gfedcb|abcdefgh|gfedcba 上面是ba|ab 这个是bab。
  • cv2.BORDER_WRAP
    • 外包装法 如:cdefgh|abcdefgh|abcdefg。
  • cv2.BORDER_CONSTANT
    • 常量法,常数值value填充。

7. 数值计算

由于是uint8类型最大255 超过相当于结果为 num%256了

我们使用以下方法保留最大值:

cv2.add(img,img2)

cv2.add(img,img2)

8. 图像融合

效果如下:

我们导入宽高相同的2张图片:

img = cv2.imread('./data/gd04.jpg')
img2 = cv2.imread('./data/gd05.jpg')
img3 = cv2.imread('./data/gd06.jpg')
print(img.shape,img2.shape,img3.shape) # (281, 600, 3) (281, 600, 3) (337, 600, 3)

如果大小不同 需要手动设置成一样的

img3 = cv2.resize(img3,(600,281))
# img3.shape (281, 600, 3)

img3 = cv2.resize(img3,(600,281))

ps: cv2.resize()另一种操作

img4 = cv2.resize(img3,(0,0),fx=2,fy=1)

我们执行:

res = cv2.addWeighted(img,0.6,img2,0.4,0)
plt.imshow(res)

res = cv2.addWeighted(img,0.6,img2,0.4,0)

R = ax1 + bx2 + c  a、b为权重 c为偏置 这里意为在原亮度上变化多少

9. 知识点总结*

读取图片:

import cv2
img = cv2.imread('./data/abv.jpg')
img2 = cv2.imread('./data/abv.jpg',cv2.IMREAD_GRAYSCALE)
img3 = cv2.imread('./data/abv.jpg',cv2.IMREAD_COLOR) 

显示图片:

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

BGR转换成灰度图、RGB:

img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img3 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) 

保存图片:

cv2.imwrite('./data/grayPhoto.jpg',img2)

视频的读取与显示:

vc = cv2.VideoCapture('./data/stu.mp4')

# 检查是否正确打开
if vc.isOpened():
    open,frame = vc.read()
else:
    open = Flase

while open:
    ret,frame = vc.read()
    if frame is None:
        break
    if ret == True:
        # 原本frame是(h,w,3)的BGR图片矩阵 经下方加入参数转换成黑白gray
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        cv2.imshow('result',gray)
        # cv2.waitKey(num) 该图片显示时间/速度 自己可以找一个合适的值
        # 27指退出键ESC 退出窗口  当然也可以是 =='q'等
        if cv2.waitKey(20)&0xFF == 27:
            break
vc.release()
cv2.destroyAllWindows()

截取图片部分:

pho = img[100:800,200:800]  # 进行切片 高100到800 宽200到800

颜色通道提取:

b,g,r = cv2.split(img)
cur_img = img.copy()
cur_img[:,:,0] = 0 # B不要了 设置为0
cur_img[:,:,1] = 0 # G不要了 设置为0
#cur_img[:,:,2] = 0 # R不要了 设置为0
cv_show('winR',cur_img)

边界填充:

top_size,bottom_size,left_size,right_size=(50,50,50,50)

# 不同的填充方法 最后参数改个type值就行
replicate = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT)
reflect101=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_CONSTANT,value=0)

数值计算:

cv2.add(img,img2)

图像融合:

img3 = cv2.resize(img3,(600,281))

res = cv2.addWeighted(img,0.6,img2,0.4,0)

总结

到此这篇关于openCV入门学习基础教程的文章就介绍到这了,更多相关openCV第一篇内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 简单了解OpenCV是个什么东西

    OpenCV于1999年由Intel建立,如今由Willow Garage提供支持.OpenCV是一个基于BSD许可[1] (开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS操作系统上.它轻量级而且高效--由一系列 C 函数和少量 C++ 类构成,同时提供了Python.Ruby.MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法.[2] 最新版本是3.3 ,2017年8月3日发布[3] . OpenCV 拥有包括 500 多个C函数的跨平台

  • opencv实现图片模糊和锐化操作

    本文为大家分享了opencv图片模糊和锐化的具体实现代码,供大家参考,具体内容如下 一.模糊操作 #!/usr/bin/env python # _*_ coding:utf-8 _*_ import cv2 as cv import numpy as np def blur_demo(image): dst = cv.blur(image, (15, 1)) cv.imshow("blur_demo", dst) src = cv.imread("F:\miao3.png&

  • openCV入门学习基础教程第一篇

    目录 前言:计算机眼中的图片 1. 图片的读取与显示 1.1 图片的读取 1.2 显示的图片 1.2.1 显示原始图片 1.2.2 灰度图 1.3 BGR转换成灰度图.RGB 2. 保存图片 3. 视频的读取与显示 4. 截取图像部分 5. 颜色通道提取 6. 边界填充 7. 数值计算 8. 图像融合 9. 知识点总结* 总结 前言:计算机眼中的图片 计算机中图片由许多个像素点组成,如一个500x500的图片,表示长宽各由500个像素点组成. 计算机中一个像素点的值在0-255表示该点亮度  0

  • MySQL基础教程第一篇 mysql5.7.18安装和连接教程

    从这篇开始,用一个新的系列文章去介绍和学习MySQL.为什么要学习MySQL,从产品角度来说,大部分软件的数据库服务还是采取关系型数据库,主要的数据库产品有Oracle.微软的MSSQL.IBM的DB2.和我们要介绍的MySQL.MySQL是很多中小型的网站服务器中数据库的首选,它有免费版,也有商业版,目前是Oracle的产品.从测试人员的角度来说,越来越多的软件产品是和数据有关,例如电商,和一些某一个领域内的数据库服务查询的软件产品.测试人员除了要做基本的软件功能测试之外,公司更希望测试人员可

  • Mybatis_plus基础教程(总结篇)

    一.简介 官网网址:http://mp.baomidou.com/ 参考教程:http://mp.baomidou.com/guide/ 二.特性 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 强大的 CRUD 操作:内置通用 Mapper.通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 支持 Lambda 形式调用:通过 Lambda

  • Visual Studio ASP.NET Core MVC入门教程第一篇

    ASP.NET Core MVC入门教程第一节课,具体内容如下 1.开始环境 visual studio 2017 社区版或其他版本.安装时勾选"Web和云"组中的"ASP.NET及网页开发"项和"其他工具"组中的".NET Core平台开发"项. 2.创建一个网页应用 (1)在 Visual Studio中, select 文件 >新建 >项目. (2) 在"新项目"对话框中的左面板中,点击&

  • Javascript入门学习资料收集整理篇

    Javascript入门学习第一篇 js基础Javascript入门学习第二篇 js类型Javascript入门学习第三篇 js运算Javascript入门学习第四篇 js对象和数组Javascript入门学习第五篇 js函数Javascript入门学习第六篇 js DOM编程Javascript入门学习第七篇 js dom实例操作Javascript入门学习第八篇 js dom节点属性说明Javascript入门学习第九篇 Javascript DOM 总结jQuery基础教程笔记适合js新手

  • Linux学习基础教程

    Linux学习基础 1.什么是Linux?  准确的说,是指Linux的kernel(系统的核心程序),其内核版权属于Linus Torvalds,在GPL(GNU General Public License)版权协议下发行, 任何人都可以自由的复制(copy), 修改(change), 套装分发(distribute),销售,但是不可以在分发时加入任何限制, 而且所有原码必须是公开的,所以任何人都可以无偿取得所有执行文件和原代码.  对于Linux用户和系统管理员来说,Linux是指包含Li

  • 什么是docker Docker入门教程第一篇

    Docker是个新生的事物,概念类似虚拟化.网上关于Docker入门的东西已经很多了.不过本文探讨了Docker的特点.特性.原理,还介绍了具有中国特色的安装测试过程,另外还谈到了Docker的社区生态和Dockerfile,并使用Dockerfile构建一个nginx环境. 缘起 在几个月前听说Docker,但是一直没有时间去研究,前一段时间趁着azure免费试用,赶紧实验一下,但是卡在了ubuntu基础镜像的下载上(由于国内网络的特殊原因),所以也就搁浅了,这里把经验和体会分享一下. Doc

  • Python常用算法学习基础教程

    本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一个算法的优劣可以用空间复杂度与时间复杂度来衡量. 一个算法应该具有以下七个重要的特征: ①有穷性(Fin

  • Android实战教程第一篇之最简单的计算器

    从今天开始,本专栏持续更新Android简易实战类博客文章.和以往专栏不同,此专栏只有实例.每个实例尽量按照知识点对应相应一章节的内容去写,循序渐进.有些实例可能会与另一个专栏有重复的文章. 开始本专栏的第一个简易案例: 首先设置两个布局文件,一个布局文件进行输入数据,获取加法运算:另一个布局文件进行显示最终结果.Activity1启动Activity2,并传递计算结果值给Activity2. main.xml: <?xml version="1.0" encoding=&quo

  • 最简单的Spring Cloud教程第一篇:服务的注册与发现(Eureka)

    前言 本文主要给大家介绍关于Spring Cloud服务注册与发现(Eureka)的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环境简单,可以在开发人员的电脑上跑.另外说明spring cloud是基于springboot的,所以需要开发中对springboot有一定

随机推荐