Python库cv2第二课:按位运算的基本进阶操作

        本周的学习计划有所搁置,这是因为本周是六级考试的时间,在准备六级,又有一整天在外做实训调查,所以真正意义上的学习时间大概是3天左右。

        回顾上一节的基础入门,我们学习到了cv2用于对图像的处理,目前按到的是对图像像素的处理,在这里就可以由小见大对于动态可视化的建立,先在这里建立一个猜想,其可视化与矩阵numpy的紧密联系。

        这里的学习我花费了一天的时间,看过了很多大佬发布的文章,其中,发现按位运算是一个很难啃的骨头,其中涉及的知识点很多,在这里,就单独作为一个入门专题学习,运用实例来条子我的基础掌握能力。

        首先,还是先深入一下按位计算,其中有一个很重要的参数,便是mask掩膜。上一节已经说到,他会遮蔽自身数组为0的区域的像素,生成黑色的蒙版。

# 这里学习一下mask参数构造掩膜的使用方式
# 首先需要读取图片,并生成整个图片的范围的蒙版
img_2 = cv2.imread('image_introdu/cat.jpg', 1)
# 得到图像的形状(266,423,3):266行,423列
img_row, img_clo, img_rgb = img_2.shape
# 生成一个全黑的rgb矩阵
mask_2 = np.zeros([img_row, img_clo], dtype=np.uint8)
# 将某个区域改成白色
mask_2[20:105, 240:325] = 255
cv2.imwrite('image_introdu/mask_cat_head.jpg', mask_2)

        其作用为在图像上构建一个蒙版,但这个蒙版又需要圈出某个范围,用于专注对某个范围的某个图像的处理,其余位置全部被遮住,便于处理。由于cv2中将图像读取为ndarray多维数组来处理,因此对numpy的基本功要求较高。

        其基础的用法如下,比如说我要圈出一个猫头,需要先建立蒙版,并用add()函数将蒙版添加到原图像上面。

img_hide = cv2.add(img_2, np.zeros(
    np.shape(img_2), dtype=np.uint8), mask=mask_2)
cv2.imwrite('image_introdu/cat_head.jpg', img_hide)

        最终圈出的猫头为:

        以下是add()函数的用法:add(src1, src2, dst=None, mask=None, dtype=None)

        src1, src2:表示需要相加的两个图像,或者一个图像与一个标量二维数组

        dst:用于保存结果的参数,一般很少用

        mask:遮罩掩码

        dtype:图像的阈值类型

        写到这里,我突然意识到,其实对于一张图像,被cv2读出来之后,是一个三维数组,但其实,不过是一个伪三维数组,真二维数组,因为对于单通道的图像来说,其实不过是一个二维数组,三通道只是强行增多了一维,完全可以将其看成二维数组来处理,cv2这个库也是这样处理的。

        另外,src1与src2的叠加方式为按照对应位置的数字叠加,最高位255,加一个标量二维数组其实等于增加亮度。

        圈出猫头之后,我们可以尝试一下,是否能够将一个logo提出,并添加在图片上。首先,我们需要导入两张图片,一张猫猫,一张logo。

# 这里我们能利用按位计算,给原图加一个logo
base_cat = cv2.imread('image_introdu/cat.jpg', 1)
base_logo = cv2.imread('image_introdu/cv2.jpg', 1)
# 先将猫猫图像放大5倍
height, width = base_cat.shape[:2]
base_cat = cv2.resize(base_cat, (int(width*5), int(height*5)),
                      interpolation=cv2.INTER_AREA)

 

        接着,我们需要得到ogo的大小,后续需要构建roi区域进行填充。由于背景是纯白色的,因此,填充roi区域是为了去除背景并将其覆盖在猫猫左上角。

        这里先进行灰度处理,处理完后的图像白色部分的颜色区域普遍在180以上(只是我的目测值,并未仔细打开数组查看),因此,采用那个threshold()函数,运用该函数反向归零的函数INV,180以上的像素全部置为0,180以下的全部置为255,表示只显示logo,其他区域都被蒙版。并反转拿到其逆掩码,逆掩码仅仅不显示logo区域,logo区域是黑色蒙版。

row, col, rgb = base_logo.shape
# 构建掩码之前需要一个灰色的logo图案,将原图案转化为灰色图案
base_logo_grey = cv2.cvtColor(base_logo, cv2.COLOR_BGR2GRAY)
# 构建一个掩码,用于遮住logo的所有区域
ret, mask_logo = cv2.threshold(base_logo_grey, 180, 255, cv2.THRESH_BINARY_INV)
# 拿到mask的逆掩码
mask_logo_inv = cv2.bitwise_not(mask_logo)

        先找出logo需要放置在左上角的全部位置,定义该矩形区域为roi,接着,在该区域进行按位与运算,并且仅仅只遮住logo的部分不显示。之后再在原始图片上仅仅只显示一个logo的形状一块区域。

# 设置logo范围的roi区域
roi_logo = base_cat[0:row, 0:col]
img1_bg = cv2.bitwise_and(roi_logo, roi_logo, mask=mask_logo_inv)
img2_fg = cv2.bitwise_and(base_logo, base_logo, mask=mask_logo)

        这样下来就可以采用add()函数,由于fg仅仅只有logo处有数字,其余logo区域全部置0,与bg处仅logo置零,其余区域全显示进行叠加,由此可以将logo白色背景完全去掉。。其中的处理方法十分巧妙,巧妙运用与运算与add()函数。

dst = cv2.add(img2_fg, img1_bg)
base_cat[0:row, 0:col] = dst
cv2.imwrite('image_introdu/cat_logo.jpg', base_cat)

        最终输出的结果如下:

        这个东西让我想到了关于背景的替换,这个很好解释对于纯色背景照片的替换,运用程序比起软件的一键抠图要更为彻底,毕竟程序精准的是每一个一个像素。 它可以将彩色照片完全灰白之后进行单色处理,其比起抠图边上带有的原始色彩,我认为,用cv2进行图像处理,能够达到人眼看不清楚的地步。

        这个想法感觉还不错,本周日,我决定在b站上传一个程序,试一下这个抠图的想法是否能够实现。

        今日的积累到此结束,按位运算与图像的叠加是一个重点,学习的展现长达两天,四个实际例子,翻阅20多篇博客,但付出总是有回报的,毕竟,滴水汇成江河。

  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值