OpenCV-Python(9):图像基础操作

news2025/4/17 16:47:18

目录

学习目标

获取图像像素并修改像素值

获取图像属性 

图像ROI

拆分及合并图像通道

图像边缘扩充


学习目标

  • 获取像素值并修改
  • 获取图像的属性(信息)
  • 图像的ROI获取
  • 图像通道拆分及合并
  • 图像扩边

获取图像像素并修改像素值

        几乎所有这些操作与Numpy 的关系要比与OpenCV 的关系更加紧密,因此熟练Numpy 可以帮助我们写出性能更好的代码。通常可以根据像素的行和列的坐标获取他的像素值。对BGR 图像而言,返回值分别为B、G、R 的值。对灰度图像而言,会返回他的灰度值(亮度),下面代码展示如何获取图像的像素:

# 导入必要的库
import cv2
import numpy as np

# 根据图片路径读入图像
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')

# 获取某一位置三通道像素的值
px=img[100,100]
print (px)

# 获取某一位置蓝色通道的值
blue=img[100,100,0]
print (blue)


# 结果展示
## [57 63 68]
## 57

可以使用以下方式修改像素值:

img[100,100]=[255,255,255]
print (img[100,100])
# 结果如下
## [255 255 255]

 警告:Numpy 是经过优化了的快速矩阵运算的软件包。所以我不推荐逐个获取像素值并修改,这样会很慢,能有矩阵运算就不要用循环。

注意:上面提到的方法通常用来选取矩阵的一个区域,比如图像前5行的后3列。对于获取每一个像素值,也可使用Numpy 的array.item() 和array.itemset() 会更好。但是返回值是标量。如果你想获得所有B、G、R 的值,你可以使用array.item() 分割他们。

获取像素值及修改的更好方法如下:

import cv2
import numpy as np

img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')

print (img.item(10,10,2))
img.itemset((10,10,2),100)
print (img.item(10,10,2))
## 50
## 100

获取图像属性 

        图像的属性值一般包括以下内容:

  1. 尺寸:图像的尺寸指的是图像的宽度和高度,通常用像素(pixel)表示。例如,一个图像的尺寸可以为640x480,表示宽度为640像素,高度为480像素。
  2. 通道数:彩色图像通常由红、绿、蓝三个通道组成,每个通道表示一种颜色分量。灰度图像只有一个通道,表示图像的亮度。通道数可以用来区分彩色图像和灰度图像。
  3. 数据类型:图像的像素值可以用不同的数据类型来表示,例如无符号整数(unsigned integer)或浮点数(float)。常见的数据类型有8位无符号整数(uint8)、16位无符号整数(uint16)、32位浮点数(float32)等。
  4. 像素值范围:图像的像素值范围取决于数据类型,例如8位无符号整数的像素值范围为0-255,16位无符号整数的像素值范围为0-65535。像素值范围可以用来判断图像的亮度级别。
  5. 位深度:图像的位深度指的是每个像素所占用的比特数。例如,8位图像的位深度为8,表示每个像素由8个比特表示。位深度可以影响图像的色彩精度和灰度级别。
  6. 颜色空间:彩色图像可以使用不同的颜色空间来表示颜色信息,常见的颜色空间有RGB、HSV、Lab等。不同的颜色空间可以表示不同的颜色分量,例如RGB颜色空间使用红、绿、蓝三个分量表示颜色。

        以上是图像的一些常见属性值,不同的图像处理库可能会提供更多的属性信息。在进行图像处理时,对这些属性值的理解和操作是非常重要的。下面介绍OpenCV中常见的图像属性处理,包括:行、列、通道、图像数据类型、图像素数目等。
img.shape 可以获取图像的形状。他的返回回值是一个包含行数、列数、通道数的元组。

print (img.shape)
## (280, 450, 3)

 注意:如果图像是灰度图,返回值仅有行数和列数。所以通过检查这个函数返回值就可以知道加载的 是灰度图还是彩色图。

 img.size 可以返回图像的像素数目。

print (img.size)
## 378000

img.dtype 返回的是图像的数据类型. 

print (img.dtype)
## uint8

注意:在除虫(debug)时img.dtype 非常重要。因为在OpenCVPython代码中经常出现数据类型的不一致。

图像ROI

        有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中眼睛的位置,我们应先应先在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索,这样会提高程序的准确性和性能。ROI 也是使用Numpy 索引来获得的。现在我们􄦸选择择球的部分并把他拷贝到图像的其他区域。

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
ball=img[280:340,330:390]
img[273:333,100:160]=bal

拆分及合并图像通道

        有时我们需要对BGR 三个通道分别进行操作。这时你就需要把BGR 拆分成单个通道。有时你需要把独立通道的图片合并成一个BGR 图像。你可以这样做:

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b,g,r=cv2.split(img)
img=cv2.merge(b,g,r)

或者这样:

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b=img[:,:,0]

 假如你想使所有像素的红色通道值都为0,你不必先拆分再赋值。你可以直接使用Numpy 索引会更快。

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
img[:,:,2]=0

 警告:cv2.split() 是一个比较耗时的操作。只有真正需要时才用它,能用Numpy 索引就尽量用。

图像边缘扩充

        如果你想在图像周围创建一个边,就像相框一样,你可以使用cv2.copyMakeBorder()函数。这经常在卷积运算或0 填充时被用到。cv2.copyMakeBorder()函数是OpenCV中用于在图像周围创建边框的函数。该函数可以用于在图像的上、下、左、右四个方向上添加指定大小和类型的边框。

函数的语法如下:

dst = cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value)

参数说明:

  • src:输入图像,可以是任意尺寸和通道数的图像。
  • top:顶部边框的大小,以像素为单位。
  • bottom:底部边框的大小,以像素为单位。
  • left:左侧边框的大小,以像素为单位。
  • right:右侧边框的大小,以像素为单位。
  • borderType:边框类型,可以是以下值之一:
    • cv2.BORDER_CONSTANT:常数边框,边框像素值为指定的value
    • cv2.BORDER_REPLICATE:复制边框,边框像素值为最边缘像素的值。
    • cv2.BORDER_REFLECT:反射边框,边框像素值沿边界反射。
    • cv2.BORDER_REFLECT_101:反射边框,边框像素值沿边界反射,但是排除边界像素。
    • cv2.BORDER_WRAP:环绕边框,边框像素值沿边界环绕。
  • value:当borderTypecv2.BORDER_CONSTANT时,用于指定边框像素值的常数。

函数返回的是添加了边框的图像。为了更好的理􄎒􄦈几种类型􄖦看下􅄑的演示程序:

import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE=[255,0,0]
img1=cv2.imread('intro.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'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')
plt.show()

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

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

相关文章

大语言模型(LLM)框架及微调 (Fine Tuning)

大语言模型(LLM) 技术作为人工智能领域的一项重要创 新在今年引起了广泛的关注。 LLM 是利用深度学习和大数据训练的人工智能系统,专门 设计来理解、生成和回应自然语言。这些模型通过分析大量 的文本数据来学习语言的结构和用法,…

跟着LearnOpenGL学习11--材质

文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里,每个物体会对光产生不同的反应。 比如,钢制物体看起来通常会比陶土花瓶更闪闪发光,一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反…

器件的静态特性

器件的静态特性 静态特性(伏安特性) 1.器件在导通或关断的状态下,其电压与电流对应关系。 2.静态过程体现器件最基本的电压与电流稳态特性。 动态特性(开关特性) 1.器件在开或关过程中,其电压、电流随时…

关于java循环结构for

关于java循环结构for 在上一篇文章中,我们了解到了while和do…while的结构以及用法,这篇文章我们主要学习一下最常用的循环结构,for结构😀,这个结构理解起来相对while结构会难一些,本篇文章内容会很多&…

深入Mybatis数据源

数据源是持久层框架中最核心的组件之一,在实际工作中比较常见的数据源有 C3P0、Apache Common DBCP、Proxool 等。作为一款成熟的持久化框架,MyBatis 不仅自己提供了一套数据源实现,而且还能够方便地集成第三方数据源。 javax.sql.DataSourc…

Linux之缓冲区的理解

目录 一、问题引入 二、缓冲区 1、什么是缓冲区 2、刷新策略 3、缓冲区由谁提供 4、重看问题 三、缓冲区的简单实现 一、问题引入 我们先来看看下面的代码:我们使用了C语言接口和系统调用接口来进行文件操作。在代码的最后,我们还使用fork函数创建…

单纯形的几何意义 Simplex

单纯形是 n 维空间 n1 个仿射无关的点的集合的凸包。在几何意义上: 1维单纯形是一个线段2维单纯形是一个三角形3维单纯形是一个四面体(tetrahedron)

MySQL线上慢SQL问题分析处理小记

相同数据量表结构,线上执行12s 本地执行0.1s过程分析 1. 慢SQL信息 SELECT t1.id,t2.idFROM t_platform_target_standard_target_index t1LEFT JOIN t_platform_target_standard t2 ON t1.target_number t2.target_numberWHERE t1.delete_flag 0 AND t2.user_num …

Linux上管理不同版本的 JDK

当在 Linux 上管理不同版本的 JDK 时,使用 yum 和 dnf 可以方便地安装和切换不同的 JDK 版本。本文将介绍如何通过这两个包管理工具安装 JDK 1.8 和 JDK 11,并利用软连接动态关联这些版本。 安装 JDK 1.8 和 JDK 11 使用 yum 安装 JDK 1.8 打开终端并…

如何在 Linux 中配置 firewalld 规则

什么是FirewallD “firewalld”是firewall daemon。它提供了一个动态管理的防火墙,带有一个非常强大的过滤系统,称为 Netfilter,由 Linux 内核提供。 FirewallD 使用zones和services的概念,而 iptables 使用chain和rules。与 ip…

22款奔驰S450L升级主动式氛围灯 浪漫婉转的氛围感

主动式氛围灯有263个可多色渐变的LED光源,营造出全情沉浸的动态光影氛围。结合智能驾驶辅助系统,可在转向或检测到危险时,予以红色环境光提示,令光影艺术彰显智能魅力。配件有6个氛围灯,1个电脑模块。 1、气候&#xf…

Spring系列学习四、Spring数据访问

Spring数据访问 一、Spring中的JDBC模板介绍1、新建SpringBoot应用2、引入依赖:3、配置数据库连接,注入dbcTemplate对象,执行查询:4,测试验证: 二、整合MyBatis Plus1,在你的项目中添加MyBatis …

IP地址的四大类型:动态IP、固定IP、实体IP、虚拟IP的区别与应用

在网络通信中,IP地址是设备在互联网上唯一标识的关键元素。动态IP、固定IP、实体IP和虚拟IP是四种不同类型的IP地址,它们各自具有独特的特点和应用场景。 1. 动态IP地址: 动态IP地址是由Internet Service Provider(ISP&#xff…

【嵌入式开发学习必备专栏】

文章目录 嵌入式开发学习必备专栏1.1 ARM Coresight SoC-400/SoC-600 专栏导读目录1.1.1 Performance Profiling1.1.2 ARM Coresight Debug 工具系列1.1.2.1 ARM DS5 系列1.1.2.2 劳特巴赫 Trace32 系列1.1.2.3 JTAG OpenOCD 系列 1.2 ARM Cache 专栏1.3 ARM AMBA Bus 专栏1.3.…

vue3 组件之间传值

vue3 组件之间传值 非常好,为啥突然开这样一篇博文,首先是因为 vue3 是未来发展的趋势。其次,vue 官方已经确认,将于2023年最后一天停止对 vue2 项目的维护,这个是官方发出的通知,并且呢,尤雨溪…

FPGA设计时序约束十四、Set_External_Delay

一、序言 在时序约束中对clock的约束还存在一种特殊的延时约束set external delay。set external delay如字面含义,设置外部的时延值,但这个外部时延主要是指反馈时延,即信号从FPGA的output端口输出后经过外部电路回到输入端口的时延值。 二…

JavaSE语法之十二:Object类

文章目录 一、概念二、获取对象信息三、对象比较equals方法四、hashcode方法 一、概念 Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的,默认会继承Object父类,即所有的类的对象都可以使用Object的引用进行…

前端基础(三十七):属性结构数据进行关键字筛选

效果 核心源码 type MenuItem {label: string;key: string | number;icon?: React.ReactNode;children?: MenuItem[];type?: group; }function filterTreeData(tree: MenuItem[], keyword: string): MenuItem[] {return tree.filter((node: MenuItem) > {if (node.labe…

macOS系统打开Linux的方法

第一步 按下[command空格键]调出搜索框,输入“终端”,打开图上第一个 第二步 如图先输入"sudo -i",敲回车键,再输入开机密码,再敲回车键就可以打开。注意:这里的密码输入不会显示在页面。 如果要…

西城微科|打气泵芯片方案SIC8833

SIC8833作为一款高性能的打气泵方案芯片,这款芯片是一个带24bitADC的8位RISC MCU,内置8k16位OTP程序存储器。具体24位双向I/O口的特性,广泛应用于气压检测和精密测量及控制系统,能满足用户的不同需求和应用场景。 以下是打气泵方案…