使用OpenCV实现图像覆盖

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达7e8ddb7cbc496a6fbfb1baff95f643cc.png

每张图像都包括RGB三个通道,分别代表红色、绿色和蓝色,使用它们来定义图像中任意一点的像素值,红绿蓝的值在0-255之间。

例如:一个像素值[255,0,0]代表全部为红色,像素值[255,255,0]是红色和绿色的混合,将显示为黄色。

但是,如果使用OpenCV读取图像,它将以BGR格式生成图像,那么[255,0,0]将代表蓝色。

使用OpenCV读取一张图像

任何图像都可以通过OpenCV使用cv2.imread()命令读取。不过,OpenCV不支持HEIC格式的图像,所以不得不使用其它类型的库,如Pillow来读取HEIC类型的图像(或者先将它们转换为JPEG格式)

import cv2image = cv2.imread(‘image.jpg’)

当读取图像之后,如果有必要的话可以将其从BGR格式转换为RGB格式,通过使用cv2.cvtColor()命令实现。

image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

覆盖

图像可以看作是是一堆像素值以类似矩阵的格式存储。任何像素的值都可以独立于其他像素进行更改。这里有一张图像,使用OpenCV读取图像:

532cf70c4c73ec295a5613f9e8493400.png

image_1

image_1 = cv2.imread(‘image_1.jpg’)
print(image_1)

这里将给出矩阵形式的一系列像素值

array([[[107, 108, 106],[107, 108, 106],[107, 108, 106],…,[ 77, 78, 76],[ 77, 78, 76],[ 76, 77, 75]],…,[[ 93, 88, 87],[ 93, 88, 87],[ 92, 87, 86],…,[ 52, 62, 62],[ 52, 62, 62],[ 52, 62, 62]]], dtype=uint8)

如果只改变图像某一区域的像素值,比如更改为[0,0,0],这部分区域将变成黑色,因为这是颜色为黑色的像素值。同样,如果将像素值更改为[255,0,0],则该区域将变为蓝色(OpenCV以BGR格式读取图像)。

image_1[50: 100, 50:100] = [255, 0, 0]

d17989cdfd8860a404f17175d7adc0fe.png

同样,这些像素值可以被另一幅图像替换,只需通过使用该图像的像素值。

为了做到这一点,我们需要将覆盖图像修改为要替换的像素值的大小。可以通过使用cv2.resize()函数来实现

image_2 = cv2.imread(‘image_2.jpg’)
resized_image_2 = cv2.resize(image_2, dsize=(100, 100))

其中,dsize 代表图像要被修改的尺寸。

现在,可以将第二张图像够覆盖在第一张图片的上面

image_1[50:150, 50:150] = resized_image_2


44aacfb141816600a5d846b17c83e1ec.png

 覆盖PNG图像

与JPEG图像不同,PNG图像有第四个通道,它定义了给定像素的ALPHA(不透明度)。

除非另有规定,否则OpenCV以与JPEG图像相同的方式读取PNG图像。

为了读取带有Alpha值的PNG图像,我们需要在读取一张图像时指定标志cv2.IMREAD_UNCHANGED。现在,这个图像已经有了四个通道:BGRA

image_3 = cv2.imread(‘image_3.png’, cv2.IMREAD_UNCHANGED)
print(image_3)
array([[[0 0 0 0][0 0 0 0][0 0 0 0]…[0 0 0 0][0 0 0 0][0 0 0 0]]…[[0 0 0 0][0 0 0 0][0 0 0 0]…[0 0 0 0][0 0 0 0][0 0 0 0]]], dtype=uint8)

323d5f0d88959fa9fe60fbd6f05cf3b9.png

然而,这个图像有4个通道,但是我们的JPEG图像只有3个通道,所以这些值不能简单地替换。

我们需要在我们的JPEG图像中添加一个虚拟通道。

为此,我们将使用 numpy。可以使用pip install numpy命令安装它。

numpy提供了一个函数numpy.dstack() 来根据深度叠加值。

首先,我们需要一个与图像大小相同的虚拟数组。

为了创建虚拟通道,我们可以使用numpy.ones()函数创建一个数组。

import numpy as npones = np.ones((image_1.shape[0], image_1.shape[1]))*255
image_1 = np.dstack([image_1, ones])

我们将其数组与255相乘,因为alpha通道的值也存在于0-255之间。

现在,我们可以用PNG图像替换图像的像素值。

image_1[150:250, 150:250] = image_3

然而,它不会给出期望的结果,因为我们将alpha通道的值改为了零。

19391b752a1628bd1137534c7de8df53.png

我们只需要替换那些具有非零值的像素值。为了做到这一点,我们可以通过检查每个像素值和替换非零值来强行执行,但这很耗时。

这里有一个更好的方法。我们可以获取要覆盖图像的alpha值。

alpha_image_3 = image_3[:, :, 3] / 255.0

我们将像素值除以255.0,以保持值在0-1之间。

 image_1 和image_3的alpha之和需要等于255。因此,我们可以创建另一个数组,其中包含和等于255的所需alpha值。

alpha_image = 1 — alpha_image_3

现在,我们可以简单的取每个图像的alpha值和每个通道的图像像素值的元素乘积,并取它们的和。

for c in range(0, 3): image_1[150:250, 150:250, c] = ((alpha_image*image_1[150:250,      150:250, c]) + (alpha_image_3*image_3[:, :, c]))

1d043aa2115701f0b871e601158cb9b4.png

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

3a2bd6d7083270fb6bc7eefe7a62a0a8.png

4a83bf4ad7fd1fd7df27231a0f18870c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值