【Python_Opencv图像处理框架】图像基本操作+90bb5729-b33a-4e82-a0d9-faa3e5cbf621

news2024/9/24 13:23:26

写在前面

很幸运能选择Python语言进行学习,这是有关Opencv的图像处理的第一篇文章,讲解了有关图像处理的一些基础操作,作为初学者,我尽己所能,但仍会存在疏漏的地方,希望各位看官不吝指正❤️


写在中间

1. 计算机眼中的图像

计算机眼中的图像由一个个像素组成, 每个像素点的值在0-255之间,代表像素点的亮度(0为最暗,255为最亮)。

  • 灰度图(黑白图)为单通道。

  • 彩色图为三通道。彩色图像包括三个颜色通道——B,G,R,分别表示蓝、绿、红。


2. 图像的表示

图像的高和宽分别代表图像在竖直和水平方向分别有多少个像素点。也等价于每个颜色通道矩阵的维度:

彩色图像为三维数组,分别为行数(高度),列数(宽度),颜色通道;

灰度图为二维数组,分别为行数(高度),列数(宽度)。


3. 基础操作

图像的读取

文件路径:不能包含中文字符

读取模式:

cv2.IMREAD_COLOR 彩色BGR模式,忽略透明度,可以用 1代替,默认编译模式。
cv2.IMREAD_GRAYSCALE 灰度模式,可以用 0 代替,将图像转换为灰度图像。
cv2.IMREAD_UNCHANGED 输出包含alpha通道的图像,可以用 -1 代替

补充说明:

Alpha通道是指图像中的透明度信息,它可以控制像素的透明度和不透明度。对于包含alpha通道的图像,在读取时需要使用IMREAD_UNCHANGED标志来保留这些透明度信息,以便后续处理和操作。如果不使用该标志,则读取的图像将被默认处理成不包含alpha通道的普通图像。

代码示例:

#包的配置
import cv2
import matplotlib.pyplot as plt
import numpy as np


img=cv2.imread(自行复制图片路径到这里) # 注意不要使用双层引号
print(img)               #打印像素
print(img.shape)         #(高,宽,通道)

第一个print会打印出来图像矩阵,由于显示太多就不展示了,大家自己尝试看看效果;

第二个print会打印出图像的高、宽和通道数,彩色图像的通道数是3,灰度图的通道数为1


图像的显示

cv2.imshow("窗口名", 要显示的图片)

窗口名,通常是字符串类型

cv2.imshow("img",img)
cv2.waitKey(0)      #等待键盘输入,输入任意键返回
cv2.destroyAllWindows()    #关闭窗口

硬核知识:

  • waitKey()内数值若为0,则表示输入任意键后退出,若为大于0的数字,则以毫秒为单位倒计时退出。

  • 新手上路,有时会碰到图片太大显示不全的问题,这时在三行代码的前面加上cv2.namedWindow('img', cv2.WINDOW_KEEPRATIO)就能解决了

  • 这是由于上述代码默认的窗口属性为cv2.WINDOW_AUTOSIZE(按照图片大小自动调整窗口大小),则当图片尺寸小于屏幕大小时,按图片尺寸设置窗口大小,显示一个完整的图片。当图片尺寸大于屏幕大小时,窗口依旧按照图片尺寸设置,则我们的屏幕不能显示整个窗口,从而产生图片显示不全的问题


4. 截取部分图像数据(ROI)

image=img[ : , : ]

冒号前后是像素区域

截取步骤就这一行代码就能实现,例如:image=img[0:200,100:200]
再加上面的图片读取,图片显示,就能完整的看到效果了

img=cv2.imread("自行复制图像路径")
image=img[0:200,100:200]
cv2.imshow("image",image)
cv2.waitKey(0)      #等待键盘输入,输入任意键返回
cv2.destroyAllWindows()    #关闭窗口

5. 视频的读取

对于视频的处理,其实和对图像的处理是相同的,原理就是利用循环将视频拆分成一帧一帧的图像,对每一帧图像进行处理

对视频的处理主要包括如下步骤:

  1. cv2.VideoCapture() 读取摄像头画面或者视频文件,本文章使用视频文件来演示
  2. 检查是否打开成功,返回一个布尔值和一帧图像的矩阵数组
  3. 对每一帧图像进行处理
#视频格式
vc=cv2.VideoCapture("自行复制视频路径")

#检查是否打开成功
if vc.isOpened():
    open, frame = vc.read()
else:
    open = False

#逐帧处理
while open:
    ret, frame = vc.read()
    if frame is None:
        break
    if ret == True:
        #灰度处理
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  #转换为灰度图
        cv2.imshow('result',gray)     # 将灰度图输出
        if cv2.waitKey(100) & 0xFF == 27: #处理完后每一帧的等待时间
            break
vc.release()
cv2.destroyAllWindows()

6. 边界填充

边界填充常见的有6种方法

BORDER_REPLICATE:复制法,也就是复制最边缘像素。 BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba BORDER_WRAP:外包装法abcdefgh|abcdefgh|abcdefg BORDER_CONSTANT:常量法,常数值填充,需要在设置一个value值,以显示填充的颜色。

  • 下面是一张示例图像,经过程序处理后得到的六张图像

在这里插入图片描述
在这里插入图片描述
代码示例:

img = cv2.imread("自行复制图像链接")

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 将BGR图片转换为RGB图片
top_size, bottom_size, left_size, right_size = (50, 50, 50, 50)  # 定义图片尺寸

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.imshow(img)  # 原图显示
plt.show()

plt.subplot(2, 3, 1), plt.imshow(img, 'gray'), plt.title('original')
plt.subplot(2, 3, 2), plt.imshow(replicate, 'gray'), plt.title('replicate')
plt.subplot(2, 3, 3), plt.imshow(reflect, 'gray'), plt.title('reflect')
plt.subplot(2, 3, 4), plt.imshow(reflect101, 'gray'), plt.title('reflect')
plt.subplot(2, 3, 5), plt.imshow(wrap, 'gray'), plt.title('wrap')
plt.subplot(2, 3, 6), plt.imshow(constant, 'gray'), plt.title('constant')

plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

7. 图像的加法

图像的加法

**前提:**两张图像拥有相同的大小和类型,在处理时应该将两幅图像相同位置的像素的灰度值(灰度图)或彩色像素各通道值(彩色图像)分别相加。通常情况下,在灰度图像中,像素用 8 个比特位(一个字节)来表示,像素值的范围是[0,255]。两个像素值在进行加法运算时,求得的和很可能超过 255,此时就将这个数%256取余。

使用价值

往小处讲:

图像的加法可以实现两张图像的融合,同时保留原图像的信息。在灰度图像中,加法会使图像变亮;而在彩色图像中,加法会使图像颜色更鲜艳。加法也可用于实现图像的平均化和均衡化。

向大处说:

  1. 图像增强:利用两个图像的加法,可以增强图像的亮度、清晰度和对比度等方面,使得图像更加鲜明、清晰。

  2. 图像融合:将两个不同的图像进行加法运算,可以实现图像的融合。例如在医学图像的处理中,将 MRI 和 CT 两个不同的图像进行加法融合,可以更清晰地显示出人体器官的位置和结构信息。

  3. 图像合成:利用图像加法可以将图像元素进行合成,生成新的图像。例如,将两个不同的图像进行叠加,可以生成动态图像或者创意图像。

  4. 噪声消除:将两个相同的图像进行加法运算,可以消除其中的噪声。由于噪声是随机变化的,将两个相同的图像进行加法运算可以消除噪声的影响,提高图像的质量。

代码示例:

import cv2
# 读取两张灰度图像
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)
# 将两张图像相同位置的像素灰度值相加
result = cv2.add(img1, img2)
# 显示结果图像
cv2.imshow('Result Image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像的融合

cv2.addWeighted(图片, 0.5, 图片, 0.4, 0)

解释:第一个参数是输入的第一张图像,第二个参数是第一张图像的权重值;第三个参数是输入的第二张图像,第四个参数是第二张图像的权重值;第五个参数是一个可选的缩放常数,可以用于调整输出图像的亮度。

img_1 = cv2.imread(自行复制图像路径)
img_2 = cv2.imread(自行复制图像路径)

# 打印出图片像素尺寸
print(img_1.shape)
print(img_2.shape)

# 统一图片尺寸
res_1 = cv2.resize(img_1, (1700, 1200))  # 图像重置函数
res_2 = cv2.resize(img_2, (1700, 1200))

# 图片融合
res = cv2.addWeighted(res_1, 0.4, res_2, 0.8, 0)
res = cv2.cvtColor(res, cv2.COLOR_BGR2RGB)  # 将BGR图片转换为RGB图片

plt.imshow(res)
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

这是将两张图片融合后的效果示例
在这里插入图片描述


写在最后

👍🏻 点赞,你的认可是我创作的动力!
⭐ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/430899.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

unity物体运动经过特定点并绘出轨迹

经过线如果有圆滑可以参考 Unity物体运动时画出轨迹_天人合一peng的博客-CSDN博客 并修改里面的数值轨迹会有变化 float angle Mathf.Min(1, Vector3.Distance(this.transform.position, targetPos) / distanceToTarget) * 45; this.transform.rotation this.t…

App灰度发布实现路径之小程序容器

灰度从字面意思理解就是存在于黑与白之间的一个平滑过渡的区域,所以说对于互联网产品来说,上线和未上线就是黑与白之分,而实现未上线功能平稳过渡的一种方式就叫做灰度发布。 灰度发布将新版本应用程序推送给一部分用户进行测试和反馈的过程…

7、ThingsBoard使用docker compose集群部署

1、概述 今天我将讲解官方文档说的使用docker compose集群部署ThingsBoard,这种部署方式也是目前企业中常用的形式,希望大家能够掌握,我不是直接使用官方的镜像,我是自己拉起代码,然后自己构建镜像,在传到服务器上,使用自己的镜像来部署。而且这种部署中间有个大坑,我…

【大数据Hadoop】HDFS3.3.1-Namenode-缓存管理

缓存管理前言缓存概念HDFS 集中式缓存有两个主要概念。缓存管理命令HDFS 集中式缓存架构CacheManager 类实现CacheReplicationMonitor前言 Hadoop 2.3.0 版本新增了集中式缓存管理(Centralized Cache Management)功能,允许用户将一些文件和目…

数字滤波器设计——FIR 滤波器

数字滤波器设计实践介绍 此示例说明如何使用 Signal Processing Toolbox 产品中的 designfilt 函数,根据频率响应设定设计 FIR 和 IIR 滤波器。该示例重点讲述低通滤波器,但大多数结果也适用于其他响应类型。 此示例主要介绍数字滤波器的设计&#xff…

MATLAB | 如何用MATLAB如何绘制各式各样精致的三元相图(ternary plot)

整了个大活,写了一个能够生成非常精致三元相图的函数,这种图主要用于展示三种变量之间的比例,本期实验绘制效果如下: 编写不易,这个工具写的脑壳痛,求多多点赞,依旧先介绍咋使用,工具…

嵌入式软件架构

总目录链接>> AutoSAR入门和实战系列总目录 总目录链接>> AutoSAR BSW高阶配置系列总目录 文章目录1 嵌入式软件分类 – BAREMETAL2 嵌入式软件分类 – 实时操作系统 (RTOS)3 嵌入式软件分类 – “通用”操作系统4 嵌入式软件分类 – 容器/微服务微服务容器5 嵌…

入行 4 年,跳槽 2 次,我摸透了软件测试这一行

最近几年行业在如火如荼的发展壮大,以及其他传统公司都需要大批量的软件测试人员,但是20年的疫情导致大规模裁员,让人觉得行业寒冬已来,软件测试人员的职业规划值得我们深度思考。 大家都比较看好软件测试行业,只是因为…

python入门(四)python眼里的图像

文章目录背景一.搭建jupyter环境Jupyter 是什么:安装Jupyter Lab1: cmd中找到 anaconda powershell prompt2.切换到python3.8环境中3. 安装Jupyter4. 运行jupyter-lab5. 备注6.命令练习二.图像的本质背景 本人工作中,用到了ai相关技术,但是java出身&…

CNStack 云服务云组件:打造丰富的云原生技术中台生态

作者:刘裕惺 CNStack 相关阅读: CNStack 多集群服务:基于OCM 打造完善的集群管理能力 CNStack 虚拟化服务:实现虚拟机和容器资源的共池管理 CNStack 云边协同平台:实现原生边缘竟能如此简单 01 前言 CNStack 2.0…

Linux网络IO精华指南

在互联网中提起网络,我们都会避免不了讨论高并发、百万连接。而此处的百万连接的实现,脱离不了网络 IO 的选择,因此本文作为一篇个人学习的笔记,特此进行记录一下整个网络 IO 的发展演变过程。以及目前广泛使用的网络模型。 1.网…

小说情感倾向分析工具

目前有很多中英文小说情感倾向工具,以下是一些常用的工具: 情感分析工具:可以对文本进行情感识别,根据文本中包含的情感信息,将其转化成情感值,通常有积极情感值、消极情感值、中性情感值等,常…

Vue3.0的生命周期

要说清这个生命周期钩子,首先我们要通过一个实例来讲解 就是点击这个按钮来切换Demo组件的显示隐藏,当然它也疯狂的操作Demo的挂载,卸载 红色是卸载流程,蓝色是挂载流程 我们写在外面可以实现,但是v3的思想是组合api因…

树状数组与线段树的应用

一、树状数组 树状数组给人的感觉就像,一直在维护前缀和一样,只是加快了前缀和的速度,再用前缀和结合题目得出一些性质,从而去解题。(一些不成熟的看法) 基础知识(一般树状数组用来处理单点修…

含氢微网优化调度模型matlab

目录 1 主要内容 模型示意图 目标函数 2 部分程序 3 程序结果 4 下载链接 1 主要内容 最近咨询含氢微网优化调度模型的同学较多,本次就分享一个高质量的源码资源。该程序方法复现《Simulation of design and operation of hydrogen energy utilization syste…

ssm拦截器

ssm拦截器 #: 与之前的过滤器不一样,过滤器是指在servlet中的,而拦截器是属于SpringMVC的,可以对请求的数据进行提前操作和后置操作: 先自己创建一个拦截器Interception类(其实人家真名叫Interceptor&…

flutter dart中用ffi调用golang或C的动态链接库

本文介绍从dart中,通过ffi方式调用golang生成的动态链接库。 go/lib.go package mainimport "C"//export GetKey func GetKey() *C.char {theKey : "123-456-789"return C.CString(theKey) }func main() {}cd go go build -buildmodec-shared…

高通QSSI方式导致CI编译失败问题记录

一、问题背景 1、QSSI说明 QSSI 是 Qualcomm Single System Image 的缩写,高通平台从Android Q开始,为了解决Android碎片化问题,把system.img和vendor.img进一步拆分,增加了QSSI编译选项,QSSI就是用来编译system.img的…

数据结构(ArrayList)

文章目录一、线性表二、顺序表2.1 ArrayList(1)概念(2)ArrayList 的构造(3)ArrayList 的方法(4) ArrayList的遍历(5)ArrayList的优缺点2.2 链表一、线性表 概…

symmetric funtion and antisymmetric function(对称性函数和反对称性函数)

symmetric funtion and antisymmetric functionantisymmetric functionsymmetric funtion附录今天看资料的时候遇到了一个说法,文中提及,f(x)f\left(x\right)f(x) 是一个 antisymmetric function,看到这个说法有点儿懵,这里特来记…