返回顶部
首页 > 资讯 > 后端开发 > Python >openCV第一篇
  • 621
分享到

openCV第一篇

opencv计算机视觉python 2023-09-11 20:09:02 621人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

文章目录 前言:计算机眼中的图片  1. 图片的读取与显示 1.1 图片的读取  1.2 显示的图片 1.2.1 显示原始图片  1.2.2 灰度图 1.3 BGR转换成灰度图、RGB 2. 保存图片 3. 视频的读取与显示 4. 截取图像

文章目录

前言:计算机眼中的图片 

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。

ac0ddb3b16ac461f8800a63b014ccb32.png

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

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

1. 图片的读取与显示

1.1 图片的读取 

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

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

9a095a8b15874db5a24eb370f9114921.png

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

fa66daf6f2e04378ad0a3e9fad429222.png

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

1.2 显示的图片

1.2.1 显示原始图片 

cv2.imshow('image',img) # 第一个参数表示窗口指定的名字 第二个为上方imGCv2.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)

9a095a8b15874db5a24eb370f9114921.png

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) 

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

ca9cba0adb754f20b82d6d042013260d.png

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

95b3b5d31c7c4a31b22b22353bfe81dc.png

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的灰度图。

899d5d3076bb4e2ebbb5886343545a50.png

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:             breakvc.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到800cv_show('win2',pho)
  • pho = img[100:800,200:800]

fa3f065b36d64fed8f9be0481322affc.png

5. 颜色通道提取

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

执行

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

78e49cf7f9334abbaf807391dcb6dc80.png

结果就是单通道图。

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

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

2b3911f2428745658ca99b850eea7069.png

6. 边界填充

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

我们以这个图片为例:

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

f4320c38f6d647c684c59065fdaa50c2.jpeg

在图片的上下左右填充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()

496a683aaecc451faf5818c736c4d6d8.png

  • 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. 数值计算

78fc17d7f1a44630a2c7855a1001adac.png

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

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

cv2.add(img,img2)
  • cv2.add(img,img2)

a3903457723941c786a7d8b1ca915878.png

8. 图像融合

效果如下:

8220c58831cb4036a68f2453b6cf61ef.png

我们导入宽高相同的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)

0139f647a62343adbf6c29076b531589.png

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 = Flasewhile 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:             breakvc.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不要了 设置为0cur_img[:,:,1] = 0 # G不要了 设置为0#cur_img[:,:,2] = 0 # R不要了 设置为0cv_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)

来源地址:https://blog.csdn.net/suic009/article/details/126067063

--结束END--

本文标题: openCV第一篇

本文链接: https://lsjlt.com/news/403696.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • openCV第一篇
    文章目录 前言:计算机眼中的图片  1. 图片的读取与显示 1.1 图片的读取  1.2 显示的图片 1.2.1 显示原始图片  1.2.2 灰度图 1.3 BGR转换成灰度图、RGB 2. 保存图片 3. 视频的读取与显示 4. 截取图像...
    99+
    2023-09-11
    opencv 计算机视觉 python
  • 第一篇python
    1、CentOS Linux release 7.2.1511 (Core) 升级python2.7.5到3.6.12、wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tg...
    99+
    2023-01-31
    第一篇 python
  • 第一篇随笔
    1 #元类 2 class myType(type): 3 def __init__(self, obj_name, base_tuple, attr_dict): 4 print(self, obj...
    99+
    2023-01-30
    第一篇 随笔
  • 第一篇 第四节 python2和p
       电脑同时安装了python2和python3,那么怎样才能自由的使用自己想用的解释器,而不是卸载掉其中一个,才可以使用,由于之前第一篇第二节已介绍过python3.6.5的安装以及环境变量的配置,那python2安装的方法步骤也类似...
    99+
    2023-01-31
    第四节 第一篇
  • 死磕MyCat使用篇之第一篇
    基本概念 直接介绍概念太枯燥了,还是拿个和背景篇相似的例子介绍业务场景:客户完成下单,快递员接受并更新运单状态,客户可以随时查看运单状态的任务。一票快递可能有多个子母件。同时,我们需要标记每个运单的状态,运...
    99+
    2024-04-02
  • php——三篇夯实根基第一篇
    目录 前言: 一、基础语法 (一)语言标记 (二)指令分隔符 (三)注释 (四)HTML和PHP区别 (五)PHP换行 (六)'echo'与'print'回显命令区别 (七)关键字 (八)基础语法实例说明  二、变量 (一)变量包含的三个内...
    99+
    2023-08-31
    php基础 php PHP
  • 我的第一篇博客
    一.Python的特点 优点 (1)优雅 明确 简单 (2)开发效率高 (3)高级语言 (4)可移植 (5)可扩展 (6)可嵌入 缺点 (1)速度慢 (2)代码不能加密 (3)代码不能利用多CPU问题   二.python的变量的命名规则...
    99+
    2023-01-30
    第一篇 博客
  • RobotFramework第一篇之环境
    定义:是一款python编写的功能自动化测试框架,具备良好的扩展性,可以进行分布性测试 1:对编程能力要求低,容易上手 2:关键字调用方式,已经定义好的功能,只需要去调用它,一个关键字实现了一个功能,关键字包括系统关键字和用户关键字 3:...
    99+
    2023-01-30
    第一篇 环境 RobotFramework
  • OpenCV-Python系列·第十一集
    自定义卷积核,如3×3、5×5、7×7、9×9、11×11 Tip:卷积核需归一化。 # -*- coding: utf-8 -*- """ Created on Sat Aug 25 14:35:33 2018 @author: M...
    99+
    2023-01-31
    一集 系列 OpenCV
  • LOG FILE SYNC概述(第一篇)
    曾经有将近半年的时间,我都在跟log file sync打交道,每次查看系统压测期间的TOP 5等待事件,log file sync都稳稳的排在第一的位置...
    99+
    2024-04-02
  • 【Python之旅】第四篇(一):Pyt
        有时候拿到一个程序接口,需要对其进行扩展,但是又不能修改原来接口的源代码,这时候就需要使用装饰器了。    有下面一个小程序,假如是别人提供给我们的调用接口:import time def sayHi():         tim...
    99+
    2023-01-31
    之旅 第四篇 Python
  • 【Python之旅】第二篇(一):Pyt
    说明:    主要是file()和open()函数的使用,但在查open()函数的帮助时,会有下面的说明:>>> help(open) …… Open a file using the file() type, retur...
    99+
    2023-01-31
    之旅 第二篇 Python
  • 【Python之旅】第五篇(一):Pyt
        只要和网络服务涉及的,就离不开Socket以及Socket编程,下面就说说Python Socket通信的基本原理。1.Socket    socket也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“...
    99+
    2023-01-31
    之旅 第五篇 Python
  • python爬虫了解第一篇
    爬虫的实际例子 搜索引擎:关键字匹配提取,前提是要将所有的页面爬一遍,然后存到自己的服务器,当用户惊醒搜索的时候,根据自己的搜索内容,搜索引擎将用户搜索信息返回给用户。 伯乐在线: 文章的搬运工(http://www.jobbole....
    99+
    2023-01-31
    爬虫 第一篇 python
  • python安装-ubuntu之第一篇
    第一步:安装ubuntu后,了解自带的python 理解python的版本 python --version 终端输入命令: which python 显示 usr/bin/python 说明终端调用是 该文件夹下的python。 whe...
    99+
    2023-01-31
    第一篇 python ubuntu
  • 【Python之旅】第七篇(一):再谈P
        主要是再进一步加深Python中关于多线程相关函数join()的理解以解多线程的执行过程。这里通过下面的例子来作进一步的说明。1.多线程与主程序代码的执行顺序关系    给出下面程序代码:#!/usr/bin/env python ...
    99+
    2023-01-31
    之旅 再谈 第七篇
  • 第七篇:suds.TypeNotFoun
    想要用Python的suds模块调用webservice地址做自动测试,但是找了很多方法都失败了,最终找到另外一个模块可以作为客户端访问服务器地址。 1.针对非安全的http from zeep import Client url = "...
    99+
    2023-01-30
    第七篇 suds TypeNotFoun
  • 第二篇:ssh.invoke_shell
    接上一篇:按照上一篇的方式,在没有对ssh.invoke_shell()执行后的登录提示符进行判断的话,那边有部分机器就回因为返回为空导致程序卡死。 正常机器  ssh.recv(9999)  命令返回内容: b'Last login: ...
    99+
    2023-01-30
    第二篇 ssh invoke_shell
  • 这是我的第一篇测试文章
    思路: 坐标型动态规划,找到规律一切就都迎刃而解了。 话不多说,一图胜千言。 ![fig1] 根据上面可以直接得到状态转移方程,fi代表的是以该位置为正方形的右下角则最大正方形的边长。 时间复杂度O(N M),空间复杂度O(N ...
    99+
    2023-01-31
    这是 第一篇 测试
  • JAVA RMI 笔记 第一篇 RMI 浓缩版
    RMI is designed to make communication between two Java programs, running in separate JVMs, as much like making a method ...
    99+
    2023-06-03
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作