CV6 图像的算术运算(以简单的抠图为例)

一 图像加法

OpenCV加法和Numpy加法之间有区别。OpenCV加法是饱和运算(无论多大都只能加到max值),而Numpy加法是模运算

>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y ) # 250+10 = 260 % 256 = 4
[4]

建议使用Opencv去添加两个图像

二 图像融合

这也是图像加法,但是对图像赋予不同的权重,以使其具有融合或透明的感觉

下面这段代码,我将两个图像融合在一起;第一幅的图像权重为0.4,第二幅图像的权重为0.6

import cv2
import numpy as np

img1 = cv2.imread('rose.jpg')
img2 = cv2.imread('homework.jpg')

img1 = cv2.resize(img1,(600,600))
dst = cv2.addWeighted(img1,0.4,img2,0.6,0)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • cv2.resize函数

功能:裁剪图片,使得两张图片的shape(或者是大小)相同。否则,会出现报错

输入参数:1.图像名 2.想要裁剪的大小

  • cv2.addWeighted函数

功能:图片融合

输入参数:1.图像1 2.图像1的权重 3.图像2 4.图像2的权重 5.融合后,每个像素点加的标量

三 按位运算(抠图)

包括按位 AND 、 OR 、 NOT 和 XOR 操作

下面我们将看到一个例子,如何改变一个图像的特定区域。 例如:把 OpenCV 的标志放在一个图像上面

怎么实现?

在我们的PS中,如果想要将一张图片的特定部分截取出来,剪切到另外一张图片上,我们需要抠图;同样在OpenCV中,我们也需要抠图

抠图完整代码:

import cv2
import numpy as np

# 加载图片
img1 = cv2.imread('rose.jpg')
img2 = cv2.imread('homework.jpg')
# 创建ROI
rows,cols,channels = img2.shape
roi = img1[0:rows,0:cols]

# 现在创建logo的掩码,并同时创建其相反的反码
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret,mask = cv2.threshold(img2gray,245,255,cv2.THRESH_BINARY)
mask = cv2.bitwise_not(mask)
mask_inv = cv2.bitwise_not(mask)

# 现在将ROI中的logo涂黑
img1_bg = cv2.bitwise_and(roi,roi,mask=mask_inv)

# 仅从logo图像中提取logo区域
img2_fg = cv2.bitwise_and(img2,img2,mask = mask)

# 将logo放入ROI并修改图像
dst = cv2.add(img1_bg,img2_fg)
img1[0:rows,0:cols] = dst
cv2.imshow('res',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

下面我们分析一下这段代码

  • 首先取出图片的shape,方便定义roi(此时两张图片的shape可以不同)
rows,cols,channels = img2.shape
  • 然后将图片灰度化,创建蒙版(官方文档上是掩码,但由于PS先入为主的关系,我更愿意叫它蒙版)
#功能:一刀切,将通道>245的像素点,置为255;反之,都置0
#输入参数:1.原图像 2.进行分类的阈值 3.高于(低于)阈值时赋予的新值 4.一个方法选择参数
mask = cv2.threshold(img2gray,245,255,cv2.THRESH_BINARY)

常用的参数有:

• cv2.THRESH_BINARY(黑白二值)
• cv2.THRESH_BINARY_INV(黑白二值反转)
• cv2.THRESH_TRUNC (得到的图像为多像素值)
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV

  • 取反操作
mask = cv2.bitwise_not(mask)
mask_inv = cv2.bitwise_not(mask)

mask的图像

mask_isv的图像

  • 与运算
# 现在将ROI中的logo涂黑
img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)

# 仅从logo图像中提取logo区域
img2_fg = cv2.bitwise_and(img2,img2,mask = mask)

我们重点对**cv2.bitwise_and(src1,src2,dst,mask)**分析

  1. src1、src2:为输入图像或标量,标量可以为单个数值或一个四元组
  2. dst:可选输出变量,如果需要使用非None则要先定义,且其大小与输入变量相同
  3. mask:图像蒙版,可选参数,为8位单通道的灰度图像,用于指定要更改的输出图像数组的元素,即输出图像像素只有mask对应位置元素不为0的部分才输出,否则该位置像素的所有通道分量都设置为0

img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv) 将图像涂黑,表明,这块底盘属于OpenCV Logo了。在mask_inv中,logo处的像素都是黑色的(0),与运算的时候,该像素点始终为0,所以呈现黑色

img2_fg = cv2.bitwise_and(img2,img2,mask = mask)将图1的logo颜色抠出来;在前面的mask中,logo处的像素都是白色的,即保留输出

  • 拼接

dst = cv2.add(img1_bg,img2_fg)

即将两个像素的B/G/R相加

个人感悟:OpenCV中的抠图,需要利用好蒙版,把想要抠出来的roi的蒙版都涂黑,不需要的就涂白,然后再与运算一下,就能抠出想要的地方

效果图
请添加图片描述
还是非常的nice的~~~

截至目前,基本的图片操作已经学完了,明天开始真正入门图像处理~

代码仓库:计算机视觉OpenCV代码仓库

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落叶随峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值