Python-OpenCV 图像的基础操作

图像的基础操作

  • 获取图像的像素值并修改
  • 获取图像的属性信息
  • 图像的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 cv2
import numpy as np

img = cv2.imread('./resource/opencv/image/messi5.jpg', cv2.IMREAD_COLOR)
ball = img[280:340, 330:390]

img2 = img.copy()
img2[273:333, 100:160] = ball

cv2.imshow('img', img)
cv2.imshow('roi', ball)
cv2.imshow('img2', img2)
cv2.waitKey(0)
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()

在这里插入图片描述

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

img = cv2.imread('./resource/opencv/image/logo/opencv-logo-white.png', cv2.IMREAD_COLOR)

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

plt.subplot(231), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(232), plt.imshow(cv2.cvtColor(replicate, cv2.COLOR_BGR2RGBA)), plt.title('replicate'), plt.xticks([]), plt.yticks([])
plt.subplot(233), plt.imshow(cv2.cvtColor(reflect, cv2.COLOR_BGR2RGBA)), plt.title('reflect'), plt.xticks([]), plt.yticks([])
plt.subplot(234), plt.imshow(cv2.cvtColor(reflect101, cv2.COLOR_BGR2RGBA)), plt.title('reflect101'), plt.xticks([]), plt.yticks([])
plt.subplot(235), plt.imshow(cv2.cvtColor(wrap, cv2.COLOR_BGR2RGBA)), plt.title('wrap'), plt.xticks([]), plt.yticks([])
plt.subplot(236), plt.imshow(cv2.cvtColor(constant, cv2.COLOR_BGR2RGBA)), 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()

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

img1 = cv2.imread('./resource/opencv/image/MachineLearnings.jpg', cv2.IMREAD_COLOR)
img2 = cv2.imread('./resource/opencv/image/100.png', cv2.IMREAD_COLOR)

print(img1.shape)
print(img2.shape)

img3 = img1 + img2
img4 = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)

imgs = np.hstack((img1, img2, img3, img4))
cv2.imshow('imgs', imgs)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

图像的位运算

图像的按位操作有: 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.mfbz.cn/a/64952.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

blender 毛发粒子

新建平面,点击右侧粒子系统,选择毛发,调整毛发长度,数量(Number),调整数量是为了避免电脑卡顿; 上面设置的每一根柱子都可以变成一个物体,点击渲染,渲染为选择…

微信云托管(本地调试)⑥:nginx、vue刷新404问题

一、nginx默认路径 1.1、默认配置文件路径:/etc/nginx/nginx.conf 1.2、默认资源路径:/usr/share/nginx/html/index.html 二、修改nginx.conf配置 (注意配置中的:include /etc/nginx/conf.d/*.conf; 里面包了一个server配置文件…

【Rust】Rust学习 第六章枚举和模式匹配

本章介绍 枚举(enumerations),也被称作 enums。枚举允许你通过列举可能的 成员(variants) 来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会…

爬虫011_元组高级操作_以及字符串的切片操作---python工作笔记030

获取元组的下标对应的值 注意元组是不可以修改值的,只能获取不能修改 但是列表是可以修改值的对吧

NSS [MoeCTF 2022]baby_file

NSS [MoeCTF 2022]baby_file 题目源码直接给了 使用data伪协议发现被ban了。 那就换一种伪协议php://filter,猜测flag在同目录下flag.php中或根目录下/flag中 php://filter/readconvert.base64-encode/resourceflag.php读取文件源码(针对php文件需要ba…

RISC-V公测平台发布:如何在SG2042上玩转OpenMPI

About HS-2 HS-2 RISC-V通用主板是澎峰科技与合作伙伴共同研发的一款专为开发者设计的标准mATX主板,它预装了澎峰科技为RISC-V高性能服务器定制开发的软件包,包括各种标准bencmark、支持V扩展的GCC编译器、计算库、中间件以及多种典型服务器应用程序。…

龙架构 Arch Linux 发行版发布

导读近日,龙架构 Arch Linux 发行版官方网站宣布结束 beta 状态,正式支持龙架构 (LoongArch)。 Arch Linux 是一种轻量级、可定制、灵活的 Linux 操作系统。作为一款简单、现代、开放的操作系统,Arch Linux 旨在基于 “KISS 原则”&#xff0…

fabric.js里toDataURL后,画布内容展示不全?

复现场景: 用fabric生成画布后,转成图片,然后直接在浏览器里打开,画布展示内容缺失 画布原图: toDataURL后链接在浏览器打开: 原因解析: base64链接太长,输入浏览器链接被截断&…

C语言每日一题:14《数据结构》复制带随机指针的链表

题目一: 题目链接: 思路一: 找相对位置暴力求解的方法: 1.复制一个新的链表出来遍历老的节点给新的节点赋值,random这个时候不去值。 2.两个链表同时遍历,遍历老链表的时候去寻找相对位置,在遍…

gma 2 教程(二)数据操作:5. 多维科学数据

多维科学数据定义 如下图所示,gma将多维栅格定义为N(>1)个普通栅格数据集(DataSet)1组(记录多维数据信息的)元数据组成的多数据集(MultiDataSets)。   注&#xff1…

【搜索框的匹配功能】

功能需求: 1. 输入关键字的同时,以下拉列表的形式显示匹配的内容; 2. 点击下拉列表的选项,跳转到对应的新的页面 注意:这里读取data.txt(检索的文件对象),会存在跨域的问题&#x…

网络编程——深入理解TCP/IP协议——OSI模型和TCP/IP模型:构建网络通信的基石

TCP/IP协议— 一、简介 TCP/IP协议,即传输控制协议/互联网协议,是一组用于在计算机网络中实现通信的协议。它由两个主要的协议组成:TCP(传输控制协议)和IP(互联网协议)。TCP负责确保数据的可靠…

本地化部署自建类ChatGPT服务远程访问

本地化部署自建类ChatGPT服务远程访问 文章目录 本地化部署自建类ChatGPT服务远程访问前言系统环境1. 安装Text generation web UI2.安装依赖3. 安装语言模型4. 启动5. 安装cpolar 内网穿透6. 创建公网地址7. 公网访问8. 固定公网地址 🍀小结🍀 前言 Te…

VBA技术资料MF41:VBA_将常规数字转换为文本数字

【分享成果,随喜正能量】时有落花至,远随流水香。人生漫长,不攀缘,不强求,按照自己喜欢的方式生活,不必太过在意,顺其自然就好。路再长也有终点,夜再黑也有尽头。 我给VBA的定义&am…

7 个最佳Node.js日志记录库和聚合器

日志记录是软件测试的重要组成部分。当我们知道错误是什么以及代码中出现问题的确切行时,调试应用程序要容易得多。 在本文中,我们将探讨与 Node.js 中的日志记录相关的各种概念,包括七个流行的日志记录库和聚合器,您可以使用它们…

成品短视频App源码,开启你的创意视频之旅!

短视频App如今已成为人们记录和分享生活的热门方式。你是否想过自己拥有一款属于自己的短视频App呢?有了短视频App源码,就能轻松实现这一愿望。本文将介绍短视频App源码的优势、开发流程和功能特点,助你快速创建个性化短视频App,开启你的创意…

04-1_Qt 5.9 C++开发指南_常用界面设计组件_字符串QString

本章主要介绍Qt中的常用界面设计组件,因为更多的是涉及如何使用,因此会强调使用,也就是更多针对实例,而对于一些细节问题,需要参考《Qt5.9 c开发指南》进行学习。 文章目录 1. 字符串与普通转换、进制转换1.1 可视化U…

万字长文解析深度学习中的术语

引言 新手在学习深度学习或者在看深度学习论文的过程中,有不少专业词汇,软件翻译不出来,就算是翻译出来也看不懂,因为不少术语是借用其他学科的概念,这里整理了一些在深度学习中常见的术语,并对一些概念进…

SpringSecurity5.7+最新案例 -- 授权 --

一、前提 书接上回 SpringSecurity5.7最新案例 – 用户名密码验证码记住我 本文 继续处理SpringSecurity授权 … 目前由 难 -> 简,即自定义数据库授权,注解授权,config配置授权 二、自定义授权 0. 数据准备 SET NAMES utf8mb4; SET …

CentOS软件包管理rpm、yum

一、软件包概述 Linux常见软件包分为两种,分别是源代码包、二进制文件包。源代码包是没有经过编译的包,需要经过GCC、C编译器编译才能运行,文件内容包含源代码文件,通常以.tar.gz、.zip、.rar结尾;二进制包无需编译&am…
最新文章