前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何用 OpenCV 制作透明渐变的蒙版?

如何用 OpenCV 制作透明渐变的蒙版?

作者头像
Frank909
发布2019-01-14 17:23:41
2.3K0
发布2019-01-14 17:23:41
举报
文章被收录于专栏:Frank909Frank909

OpenCV 可以进行一系列的图像处理,也能够直接的绘制图片,但涉及到一些复杂的图像处理时,没有现成的 API 可以使用,这个时候需要我们自己实现代码。

本文介绍如何利用现成的 API 去实现一个比较复杂,但可能比较常见的图像处理操作,那就时给图片添加一个透明渐变的效果。

大家可以看看效果图。

这里写图片描述
这里写图片描述

左边的图像是原始图像,右边的图像经过处理添加了一层蒙版。

需要说明的是,本文的代码基于 OpenCV3.3 和 python2.7 版本编写。

如何制作渐变效果?

我的思路是先创立一幅透明的图像,然后在透明的图像上进行像素点颜色值的操作。

这里写图片描述
这里写图片描述

上面右边的图像就是我创建的渐变图像,它大小与原图片一样的。

我以垂直渐变为例说明。

如何实现这样的渐变呢?

我们知道 RGB 模式下,每个颜色通道的取值范围是 0 ~ 255。

我们可以给予一个起始颜色,(255,255,0)。

然后再给定一个结束颜色,(0,0,0)。

不难发现,每个通道有颜色的差距。

渐变是有范围的,范围可以用 X 和 Y 轴上的像素距离表示。

那么,建立一个公式让距离与颜色的变化产生联系,也就不难理解。

比如,所有的 y 坐标值为 0 的像素颜色都为 (255,255,0),这个起始颜色用 color_start 表示,所有的 y 坐标值为 512 的像素颜色都为 (0,0,0),用 color_end 表示渐变结束颜色。

渐变的颜色距离 dist 是 512 - 0 = 512

每个颜色通道也有颜色变化,我们分别处理就好了。

以红色通道为例。

渐变距离是 512,颜色变化幅度是 0 - 255 = -255.

我们不难得到一个颜色变化的系数 g_r

代码语言:javascript
复制
g_r = -255 / 512 = -0.498

有了这个系数,就可以通过公式计算出相对于渐变开始的位置的每个坐标颜色值。

代码语言:javascript
复制
color_dst = color_start + dist * g_r

3 个颜色通道分别处理,就可以得到完整的渐变图像。

代码如下:

代码语言:javascript
复制
def vertical_grad(src,color_start,color_end):
    h = src.shape[0]

    print type(src)

    # 创建一幅与原图片一样大小的透明图片
    grad_img = np.ndarray(src.shape,dtype=np.uint8)

    # opencv 默认采用 BGR 格式而非 RGB 格式
    g_b = float(color_end[0] - color_start[0]) / h
    g_g = float(color_end[1] - color_start[1]) / h
    g_r = float(color_end[2] - color_start[2]) / h

    for i in range(h):
        for j in range(src.shape[1]):

                grad_img[i,j,0] = color_start[0] + i * g_b
                grad_img[i,j,1] = color_start[1] + i * g_g
                grad_img[i,j,2] = color_start[2] + i * g_r

    return grad_img

我们可以写代码测试一下。

代码语言:javascript
复制
if __name__ == '__main__':
    img = cv2.imread('../lena.jpg')
    grad_img = vertical_grad(img,(0,0,255),(0,0,0))

    cv2.imshow('lena',img)
    cv2.imshow('gradients',grad_img)

    cv2.waitKey()
    cv2.destroyAllWindows()
这里写图片描述
这里写图片描述

但有了渐变图像还不够,我们需要将渐变应用到原始图像当中。

OpenCV 图像混合

这个其实很简单,只要借助于 OpenCV 自带的混合方法就好了。

代码语言:javascript
复制
blend = cv2.addWeighted(img,1.0,test,0.6,0.0)

第一个参数是要混合的原始图片,第二个参数对应第一张图片的 alpha 值,第三个参数是要混合的图像,它与第一张图片的尺寸和通道都是一致的,后面的参数代表混合时,它的 alpha 取值。最后一位是 gamma 参数,默认为 0.

alpha 就是透明度的参数,在上面代码中,我让原始图片保持了 1.0 的透明度,而让它上面的渐变图像只有 0.6,最终实现了图像的混合操作。

测试代码:

代码语言:javascript
复制
img = cv2.imread('../lena.jpg')

grad_img = vertical_grad(img,(0,255,255),(0,0,0))
blend = cv2.addWeighted(img,1.0,grad_img,0.6,0.0)

cv2.imshow('lena',img)
cv2.imshow('gradients',grad_img)
cv2.imshow('blend',blend)

q = cv2.waitKey()
cv2.destroyAllWindows()

效果如下:

这里写图片描述
这里写图片描述

本文只讲了一个方向的渐变效果,其他方向大家可以自己思考一下,想想怎么实现,其实思路差不多。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何制作渐变效果?
  • OpenCV 图像混合
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档