Python-OpenCV 图像的基础操作

news2024/10/6 13:12:22

图像的基础操作

  • 获取图像的像素值并修改
  • 获取图像的属性信息
  • 图像的ROI区域
  • 图像通道的拆分及合并
  • 图像扩边填充
  • 图像上的算术运算
    • 图像的加法
    • 图像的混合
    • 图像的位运算

获取图像的像素值并修改

首先读入一副图像:

import numpy as np
import cv2

# 1.获取并修改像素值
# 读取一副图像, 根据像素的行和列的坐标获取它的像素值, 对于RGB图像而言, 返回RGB的值, 对于灰度图则返回灰度值

img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_COLOR)
px = img[200, 100]
print(px)	# [24 18 11]
 
blue = img[200, 100, 0]
print(blue)  # 24

# 修改101行,101列的像素值
img[101, 101] = [255,255,255]
print(img[101,101])

cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

import numpy as np
import cv2

# numpy是经过优化了的进行快速矩阵运算的包, 所以不推荐逐个获取像素值并修改能矩阵运算就不要用循环。
# 例如前5行的后3列, 用numpy的array.item()和array.itemset()会更好。 但是返回是标量, 如果想获得所有RGB
# 的值, 需要使用array.item()分割他们。

img = cv2.imread('./resource/image/1.jpg')
print(img.item(10, 10, 2))

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

获取图像的属性信息

img = cv2.imread(‘./resource/image/1.jpg’, cv2.IMREAD_COLOR)
img.shape: 图像的形状(包括行数,列数,通道数的元组)
img.size : 图像的像素数目
img.dtype :图像的数据类型

import numpy as np
import cv2

# 图像属性包括: 行, 列, 通道, 图像数据类型, 像素数目等
# 如果图像是灰度图, 返回值仅有行数和列数, 所以通过检查返回值可以判断是灰度图还是彩色图
img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_COLOR)
print(img.shape)  #  彩色图(1080, 1920, 3) 

img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_GRAYSCALE)
print(img.shape)  # 灰度图(1080, 1920)


# img.size 获取图像像素数
img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_COLOR)
print(img.size) # 6220800
print(img.dtype)# uint8

img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_GRAYSCALE)
print(img.size) # 2073600
print(img.dtype)# uint8

图像的ROI区域

ROI(regionofinterest),感兴趣区域。机器视觉、图像处理中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域,称为感兴趣区域,ROI。在Halcon、OpenCV、Matlab等机器视觉软件上常用到各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。

import numpy as np
import cv2

img = cv2.imread('./resource/image/4.jpg')
ball = img[20:70,30:80]     # 获取一块图像
img[40:90,50:100] = ball    # 指定位置绘制一块图像

cv2.imshow('image', img)
cv2.waitKey(0)&0xFF
cv2.destroyAllWindows()

图像通道的拆分及合并

有时需要对 BGR 三个通道分别进行操作。这时就需要把 BGR 拆
分成单个通道。有时需要把独立通道的图片合并成一个 BGR 图像。
注:cv2.split()是比较耗时的操作,尽量使用numpy索引操作。

import numpy as np
import cv2

img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_COLOR)
# split函数,拆分图像数据
(b,g,r) = cv2.split(img) 
img2 = cv2.merge([b,g,r]) # 合并数据
print(r.shape)
print(g.shape)
print(b.shape)

# Numpy索引拆分图像数据
img = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_COLOR)
b = img[:,:,0] # 拆分b通道
g = img[:,:,1] # 拆分g通道
r = img[:,:,2] # 拆分r通道

# 通道像素赋值
img[:,:,2]= 0 #
print(r.shape)
print(g.shape)
print(b.shape)

img3 = cv2.merge([b,g,r])

cv2.imshow('img', img)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像扩边填充

如果想在图像周围创建一个边,就像相框一样,你可以使用cv2.copyMakeBorder()函数。这经常在卷积运算或 0 填充时被用到。这个函数包括如下参数:

  • src 输入图像

  • top, bottom, left, right 对应边界的像素数目。

  • borderType 要添加那种类型的边界,类型如下:

    1. cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要
      下一个参数( value)。
    2. cv2.BORDER_REFLECT 边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb
    3. cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT
      跟上面一样,但稍作改动。例如: gfedcb|abcdefgh|gfedcba
    4. cv2.BORDER_REPLICATE 重复最后一个元素。例如: aaaaaa|
      abcdefgh|hhhhhhh
    5. cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh|
      abcdefgh|abcdefg
  • value 边界颜色,如果边界的类型是 cv2.BORDER_CONSTANT

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 边界填充
img = cv2.imread('./resource/image/opencv-logo2.png')

# BORDER_REPLICATE:复制法,复制最边缘的像素
# BORDER_REFLECT:反射法
# BORDER_REFLECT101:反射法
# BORDER_WRAP:外包装
# BORDER_CONSTANT:常量法

blue = [255, 0, 0]
replicate = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_REPLICATE)   
reflect = cv2.copyMakeBorder(img, 10, 10, 10,10, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_REFLECT101)
wrap = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=blue)

plt.subplot(231), plt.imshow(img, 'gray'), plt.title('original'), plt.xticks([]),plt.yticks([])
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('replicate'), plt.xticks([]),plt.yticks([])
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('reflect'), plt.xticks([]),plt.yticks([])
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('reflect101'), plt.xticks([]),plt.yticks([])
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('warp'), plt.xticks([]),plt.yticks([])
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('constant'), plt.xticks([]),plt.yticks([])
plt.show()

在这里插入图片描述

图像上的算术运算

图像上的算术运算有:加法,减法,位运算等
涉及的函数有:cv2.add(), cv2().addWeighted()等

图像的加法

可以使用函数 cv2.add() 将两幅图像进行加法运算,当然也可以直接使
用 numpy, res=img1+img2。两幅图像的大小,类型必须一致,或者第二个
图像可以是一个简单的标量值。

注意: OpenCV 中的加法与 Numpy 的加法是有所不同的。 OpenCV 的加法
是一种饱和操作,而 Numpy 的加法是一种模操作。如下例子所示:

x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y))  #  250 + 10 = 260 > 255, uint8 最大值255
# 输出结果[[255]]

print(x + y) # 250_10=260%255=4
# 输出结果[[4]] 

图像的混合

其实也是加法运算,但不同的是两幅图像的权重不同,给人一种混合或透明的感觉。图像混合计算公式如下:
g ( x ) = ( 1 − α ) f 0 ( x ) + α f 1 ( x ) g(x) = (1-\alpha)f_0(x) + \alpha f_1(x) g(x)=(1α)f0(x)+αf1(x)
通过修改 α \alpha α的值(0-1),可以实现不同权重的混合。
d s t = α ∗ i m g 1 + β ∗ i m g 2 + γ dst = \alpha*img1 + \beta*img2+\gamma dst=αimg1+βimg2+γ
这里 γ \gamma γ的值为0。

dst2 = cv2.addWeighted(img1, 0.3, img2, 0.7, 0)

import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('./resource/image/1.jpg', cv2.IMREAD_COLOR)
img2 = cv2.imread('./resource/image/2.jpg', cv2.IMREAD_COLOR)

dst1 = img1 + img2
dst2 = cv2.addWeighted(img1, 0.3, img2, 0.7, 0)

plt.subplot(231), plt.imshow(img1), plt.title('img1')
plt.subplot(232), plt.imshow(img2), plt.title('img2')
plt.subplot(233), plt.imshow(dst1), plt.title('img1+img2')
plt.subplot(234), plt.imshow(dst2), plt.title('addWeighted(img1+img2)')
plt.show()

图像的位运算

图像的按位操作有: AND, OR, NOT, XOR 等。当我们提取图像的一部分,选择非矩形 ROI 时这些操作会很有用。下面的例子就是教给我们如何改变一幅图的特定区域。

  • cv2.bitwise_and() 与
  • cv2.bitwise_or() 或
  • cv2.bitwise_not() 非
  • cv2.bitwise_xor() 异或
import numpy as np
import cv2

img1 = cv2.imread('./resource/image/1.jpg')
img2 = cv2.imread('./resource/image/opencv-logo.png')

# 放置logo在左上角
rows, cols, channels = img2.shape
roi = img1[0:rows,0:cols]

img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY) # 二值化处理
mask_inv = cv2.bitwise_not(mask)

img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)

dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst

cv2.imshow('logo', img2)    
cv2.imshow('gray', img2gray)
cv2.imshow('mask', mask)       
cv2.imshow('mask_inv', mask_inv)
cv2.imshow('bg', img1_bg)
cv2.imshow('fg', img2_fg)
cv2.imshow('res', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

商用服务机器人公司【Richtech Robotics】申请纳斯达克IPO上市

来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,总部位于美国内华达州拉斯维加斯由华人领导的商用服务机器人公司【Richtech Robotics】近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯达克IPO上市&am…

springboot互联网智慧3D导诊系统源码 智慧医疗系统源码

互联网智慧3D导诊系统源码 通过智能导诊,进行自助问询及挂号服务,减轻导诊台护士压力,挂号更加方便快捷。 技术架构:springbootredismybatis plusmysqlRocketMQ 智慧导诊系统开发原理 导诊系统从原理上大致可分为基于规则模板…

《深度探索c++对象模型》第六章笔记

非原创,在学习 6 执行期语意学(Runtime Semantics) 有这样一个简单的案例: if (yy xx.getValue()) {// ... } 其中,xx和yy的定义为: X xx; Y yy; class Y定义为: class Y { public:Y();~Y();bool operator(con…

目前Java后端就业前景怎么样?

前言 并不乐观,看看现在的就业形式就知道了,基本上是僧多粥少的情况,你可能会看到很多编程语言排行榜或者流行榜中Java的排名很高,如同下面这种: 看排名确实可以粗略的得知语言当下的流行度、使用率,但是它…

对齐控制大作战:align-content 和 align-items,到底谁才是真正的垂直大将?

🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 🖥️ Node专栏:Node.js从入门到精通 🖥️ TS知识总结:十万字TS知识点总结 👉 你的一键三连是我更新的最大动力❤️!…

算法通过村第二关-链表黄金笔记|K个一组反转

文章目录 前言链表反转|K个一组翻转链表解题方法:头插法处理:穿针引线法处理: 总结 前言 提示:没有人天生就喜欢一种气味而讨厌另一种气味。文明的暗示而已。 链表反转|K个一组翻转链表 给你链表的头节点 head ,每 k…

毕业后想往开发上位机的方向发展,不知道怎么样?

上位机的薪资目前还可以,虽然不能比肩互联网,但是在所有行业中应该还算比较高的,二十几万的年薪比较容易。 还不错,最流行的开发方式有labview和C#,建议选C#。工控主要还是集中在长三角和珠三角,搞上位机很…

CentOS 安装 Jenkins

本文目录 1. 安装 JDK2. 获取 Jenkins 安装包3. 将安装包上传到服务器4. 修改 Jenkins 配置5. 启动 Jenkins6. 打开浏览器访问7. 获取并输入 admin 账户密码8. 跳过插件安装9. 添加管理员账户 1. 安装 JDK Jenkins 需要依赖 JDK,所以先安装 JDK1.8。输入以下命令&a…

为什么亚马逊购物车会丢失呢?如何找回来呢?

想要找回店铺购物车,必须先清楚购物车丢失的原因,只有找到原因,对症下药,才能以最快的速度找回。 一、亚马逊购物车丢失的原因: 1.listing新上架 通常来说,新上架的Listing,该Listing在亚马逊…

HIVE优化之不需要参数优化

#1.数据倾斜 什么是数据倾斜? 一部分数据多 一部分数据少 造成的结果: MR运行过慢 主要是shuffle和reduce过程慢 分组聚合导致数据倾斜 Hive未优化的分组聚合 方法1:在MAP端直接聚合(分组聚合优化),减少…

wxwidgets Ribbon使用wxRibbonToolBar实例

wxRibbonToolBar就是工具栏,一下是实现的效果,界面只是功能展示,没有美化 实现代码如下所示: MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(800, 600)) …

超越传统线程:探索Java Loom协程(纤程/虚拟线程)的无限潜力

《超越传统线程:探索Java Loom协程(纤程/虚拟线程)的无限潜力》 一、Java协程的发展历程 Java协程的发展历程可以概括为以下几个阶段: 1963年,协程的概念被正式提出,它的诞生甚至早于线程。2007年,Kilim项目发布&…

【C++】map和set在OJ中的应用

文章目录 前言1. 剑指 Offer : 复杂链表(带随机指针)的复制1.1 思路分析(利用map搞)1.2 AC代码 2. 前K个高频单词2.1 思路1AC代码2.2 思路2AC代码2.3 思路3AC代码 3. 两个数组的交集3.1 思路分析3.2 AC代码 前言 上一篇…

AI和ChatGPT:人工智能的奇迹

AI和ChatGPT:人工智能的奇迹 引言什么是人工智能?ChatGPT:AI的语言之王ChatGPT的工作原理ChatGPT的优势和挑战AI和ChatGPT的未来展望结论 引言 人工智能(Artificial Intelligence,简称AI)是一项令人兴奋的…

收集到大量的名片怎么转为excel?

来百度APP畅享高清图片 参加完展会或集体会议,是不是收了一大堆名片,保管起来超级麻烦,还容易丢三落四?别急,我们有办法!把名片转成电子版保存到电脑上就完美啦!但要是名片数量有点多&#xff0…

Linux文本三剑客之awk

目录 前言 awk 1.认识awk 2.使用awk 2.1语法 2.2常用命令选项 2.3awk变量 2.3.1内置变量 2.3.2自定义变量 2.4printf命令 awk例题 前言 awk、grep、sed是linux操作文本的三大利器,合称文本三剑客,也是必须掌握的linux命令之一。三者的功能都是…

什么是全局代理,手机怎么设置全局代理

目录 什么是全局代理 全局代理的优缺点 优点 缺点 手机怎么设置全局代理 注意事项 总结 在计算机网络和信息安全中,全局代理是一种常用的技术手段,用于将网络流量通过代理服务器进行转发和处理。本文将介绍什么是全局代理,探讨全局代理…

Stable Diffusion - Candy Land (糖果世界) LoRA 提示词配置与效果展示

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/132145248 糖果世界 (Candy Land) 是一个充满甜蜜和奇幻的地方,由各种各样的糖果和巧克力构成。在糖果世界,可以看到&…

el-select 三级联动

一、效果图 二、思路&#xff1a;先请求一级select数据&#xff0c;通过选中的id请求二级数据&#xff0c;以此类推&#xff01; 三、代码 <template><div><el-card><el-form :inline"true"><el-form-item label"一级">&l…

如何用正确的姿势监听Android屏幕旋转

作者&#xff1a;37手游移动客户端团队 背景 关于个人&#xff0c;前段时间由于业务太忙&#xff0c;所以一直没有来得及思考并且沉淀点东西&#xff1b;同时组内一个个都在业务上能有自己的思考和总结&#xff0c;在这样的氛围下&#xff0c;不由自主的驱使周末开始写点东西&…