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

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

一 图像加法


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的图像


e3516755509db77f.png


mask_isv的图像


d54693ec08b81b2b.png


  • 与运算


# 现在将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)**分析


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


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


9d266a0663757a0c.png


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


70c960418a026d15.png


  • 拼接


dst = cv2.add(img1_bg,img2_fg)


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


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


效果图


2dece50c123a44bea27286b1d32be148.png


还是非常的nice的~~~


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


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

相关文章
|
10月前
|
机器学习/深度学习 人工智能 安全
《昇腾芯片:鸿蒙NEXT人工智能算力体系的核心驱动力》
在人工智能快速发展的背景下,鸿蒙NEXT操作系统与昇腾芯片的结合带来了重大变革。昇腾芯片凭借卓越的计算性能(如昇腾910的320 TFLOPS半精度算力),加速模型训练和推理,缩短训练时间,提升效率。它与鸿蒙NEXT深度融合,实现高效协同,支持多场景应用,从云端到终端提供强大算力,并通过星盾安全架构保障数据安全。这一组合为智能生态的发展奠定了坚实基础。
675 14
|
异构计算 Windows
嵌入式硬件电路常用设计软件有哪些
嵌入式硬件电路常用设计软件各有其特点和优缺点。在选择软件时,用户应根据自己的实际需求、预算以及学习曲线等因素进行综合考虑。
399 7
|
XML 物联网 API
服务端和客户端 RESTful 接口上传 Excel 的 Python 代码
本文作者木头左是物联网工程师,分享如何使用 Python 和 Flask-RESTful 构建一个简单的 RESTful API,实现文件上传功能,特别支持Excel文件。通过安装Flask和Flask-RESTful库,创建Flask应用,实现文件上传接口,并将其添加到API。该方法具有简单易用、灵活、可扩展及社区支持等优点。
服务端和客户端 RESTful 接口上传 Excel 的 Python 代码
|
存储 Nacos 数据安全/隐私保护
【SpringCloud】Nacos的安装、Nacos注册、Nacos服务多级存储模型
【SpringCloud】Nacos的安装、Nacos注册、Nacos服务多级存储模型
258 1
|
9月前
|
人工智能 数据可视化 Java
打造动态数据可视化:JavaScript与AI的完美结合
在快速发展的技术世界中,Java作为广泛应用的编程语言,持续占据重要地位。本文探讨如何将AI技术,如DeepSeek,融入Java高级应用开发,实现智能代码生成、优化与自动化测试,提升开发效率和代码质量。AI通过分析大量代码库,自动生成高质量代码片段,减少重复劳动,并提出优化建议,帮助开发者编写更高效、安全的代码。未来,AI将进一步推动Java开发智能化,降低开发门槛,助力创新。
|
JavaScript
Vue组件传值异步问题--子组件拿到数据较慢
Vue组件传值异步问题--子组件拿到数据较慢
626 154
|
搜索推荐 Python
快速排序的 Python 实践:从原理到优化,打造你的排序利器!
本文介绍了 Python 中的快速排序算法,从基本原理、实现代码到优化方法进行了详细探讨。快速排序采用分治策略,通过选择基准元素将数组分为两部分,递归排序。文章还对比了快速排序与冒泡排序的性能,展示了优化前后快速排序的差异。通过这些分析,帮助读者理解快速排序的优势及优化的重要性,从而在实际应用中选择合适的排序算法和优化策略,提升程序性能。
357 1
|
弹性计算 监控 网络协议
分析网络超时问题的最佳实践
对于云上的用户来说,业务日志里面报超时问题处理起来往往比价棘手,因为1) 问题点可能在云基础设施层,也有可能在业务软件层,需要排查的范围非常广;2) 这类问题往往是不可复现问题,抓到现场比较难。在本文里就分析下如何来分辨和排查这类问题的根本原因。
分析网络超时问题的最佳实践
|
消息中间件 缓存 Java
Java 最常见的面试题:怎么保证缓存和数据库数据的一致性?
Java 最常见的面试题:怎么保证缓存和数据库数据的一致性?
|
SQL 大数据 测试技术
奇迹降临!解锁 Flink SQL 简单高效的终极秘籍,开启数据处理的传奇之旅!
【8月更文挑战第9天】在大数据处理领域,Flink SQL 因其强大功能与简洁语法深受开发者青睐。本文分享了编写高效 Flink SQL 的实用技巧:首先需深刻理解数据特性与业务目标;其次,合理运用窗口函数(如 TUMBLE 和 HOP)可大幅提升效率;优化连接操作,优先采用等值连接并恰当选择连接表;正确选取数据类型以减少类型转换开销;最后,持续进行性能测试与调优。通过这些方法,我们能在实际项目中(如实时电商数据分析)更高效地处理数据,挖掘出更多价值。
222 6