OpenCV图像处理 - 为图像添加Logo

1,目的

将logo图标叠加到一张图片的右上角,要求有颜色的区域为不透明,例如将阿里影业的Logo叠加到战狼2的海报上,原始图和效果图如下。

wolf.jpg
ali-movie.png
img_target.png

2,思路

不同的logo有不同的处理方法,有的是黑色需要透明,有的是白色需要透明,但是,整理的思路是一致的。

如下图所示,从上向下,对要形成的效果进行分解,一共分为3层。

  • 第一层需要第二层的两张图片,做cv2.add运算即可
  • 第二层第一张图片需要第三层前两张图片,做cv2.bitwise_and运算即可,后一张做mask
  • 第二层第二张图片需要第三层后两张图片,做cv2.bitwise_and运算即可,后一张做mask
method of img deal.png

在分解过程中,需要思考和明确要调用的OpenCV函数。如果一步解决不了,就拆分成多步解决。

3,步骤分析

基于上述思路,制定详细的图像处理步骤,并进行编码调试。处理步骤如下图所示。

ali-logo deal process.png

3.1,读取logo图片,并对logo按照20%进行缩放

img_logo = cv2.imread("d:/1/ali-movie.png", cv2.IMREAD_COLOR)
img_logo = cv2.resize(img_logo, (0, 0), fx=0.2, fy=0.2, interpolation=cv2.INTER_NEAREST)

3.2,对logo进行灰度化处理,得到两个mask

img_logo_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY)
ret, img_logo_mask = cv2.threshold(img_logo_gray, 200, 255, cv2.THRESH_BINARY)  # 二值化函数
img_logo_mask1 = cv2.bitwise_not(img_logo_mask)

3.3,提取目标图片的ROI

img_target = cv2.imread("d:/1/wolf.jpg", cv2.IMREAD_COLOR)
rows, cols, channel = img_logo.shape
rows1, cols1, channel1 = img_target.shape
img_roi = img_target[:rows, cols1 - cols:cols1].copy()

3.4,ROI和Logo图像融合

img_res0 = cv2.bitwise_and(img_roi, img_roi, mask=img_logo_mask)
img_res1 = cv2.bitwise_and(img_logo, img_logo, mask=img_logo_mask1)
img_res2 = cv2.add(img_res0, img_res1)
# img_res2 = img_res0 + img_res1
img_target[:rows, cols1 - cols:cols1] = img_res2[:, :]
cv2.imwrite("img_target.png", img_target)

4,疑难点介绍

4.1,cv2.add与矩阵相加的区别

测试程序

import numpy as np
import cv2
x = np.uint8([250])
y = np.uint8([10])
print cv2.add(x,y)   #输出# [[255]]
print x+y            #输出# [4]  (250+10)%255

测试结论

  • cv2.add方法和numpy矩阵相加,都可以完成两张图片的相加运算
  • numpy矩阵相加是模运算
  • cv2.add是渗透运算,如果元素之和大于255,则按照255返回,可以直接相加两张图片试试效果,代码和效果图如下所示
img_logo = cv2.imread("d:/1/ali-movie.png", cv2.IMREAD_COLOR)
img_target = cv2.imread("d:/1/wolf.jpg", cv2.IMREAD_COLOR)
print img_logo.shape, img_target.shape
img_new_add = cv2.add(img_target[:516, :798], img_logo[:516, :798])
cv2.imshow("img_new_add", img_new_add)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.add.png

4.2,matplotlib的subplot简单介绍

代码如下,效果图如method of img deal.png所示。

  • 代码
# 显示图片,调用matplotlib展示
plt.figure()
plt.subplot(332), plt.imshow(img_convert(img_res2), cmap='gray'), plt.title("img_res2")
plt.subplot(323), plt.imshow(img_convert(img_res0), cmap='gray'), plt.title("img_res0")
plt.subplot(324), plt.imshow(img_convert(img_res1), cmap='gray'), plt.title("img_res1")
plt.subplot(3, 4, 9), plt.imshow(img_convert(img_roi), cmap='gray'), plt.title("img_roi")
plt.subplot(3, 4, 10), plt.imshow(img_convert(img_logo_mask), cmap='gray'), plt.title("img_logo_mask")
plt.subplot(3, 4, 11), plt.imshow(img_convert(img_logo), cmap='gray'), plt.title("img_logo")
plt.subplot(3, 4, 12), plt.imshow(img_convert(img_logo_mask1), cmap='gray'), plt.title("img_logo_mask1")
plt.show()
  • 效果图
method of img deal.png

5,源码奉上

# coding:utf8

import numpy as np
import cv2
from matplotlib import pyplot as plt


# 图像处理,将logo图标叠加到一张图片的右上角,要求有颜色的区域为不透明
def img_deal():
    # 1,对logo进行缩放,按照20%进行
    img_logo = cv2.imread("d:/1/ali-movie.png", cv2.IMREAD_COLOR)
    img_logo = cv2.resize(img_logo, (0, 0), fx=0.2, fy=0.2, interpolation=cv2.INTER_NEAREST)
    # cv2.imshow("img_logo", img_logo)

    # 2,对logo做清洗,白色区域是255,其他区域置为黑色0
    img_logo_gray = cv2.cvtColor(img_logo, cv2.COLOR_BGR2GRAY)
    ret, img_logo_mask = cv2.threshold(img_logo_gray, 200, 255, cv2.THRESH_BINARY)  # 二值化函数
    img_logo_mask1 = cv2.bitwise_not(img_logo_mask)
    # cv2.imshow("img_logo_gray", img_logo_gray)
    # cv2.imshow("img_logo_mask", img_logo_mask)

    # 3,提取目标图片的ROI
    img_target = cv2.imread("d:/1/wolf.jpg", cv2.IMREAD_COLOR)
    rows, cols, channel = img_logo.shape
    rows1, cols1, channel1 = img_target.shape
    img_roi = img_target[:rows, cols1 - cols:cols1].copy()
    # cv2.imshow("img_roi", img_roi)

    # 4,ROI和Logo图像融合
    img_res0 = cv2.bitwise_and(img_roi, img_roi, mask=img_logo_mask)
    img_res1 = cv2.bitwise_and(img_logo, img_logo, mask=img_logo_mask1)
    img_res2 = cv2.add(img_res0, img_res1)
    # img_res2 = img_res0 + img_res1
    img_target[:rows, cols1 - cols:cols1] = img_res2[:, :]
    cv2.imwrite("img_target.png", img_target)

    # 显示图片,调用opencv展示
    # cv2.imshow("img_res0", img_res0)
    # cv2.imshow("img_res1", img_res1)
    # cv2.imshow("img_res2", img_res2)
    # cv2.imshow("img_target", img_target)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

    # 显示图片,调用matplotlib展示
    plt.figure()
    titles = ["img_logo", "img_logo_gray", "img_logo_mask", "img_logo_mask1", "img_roi", "img_res0", "img_res1",
              "img_res2"]
    imgs = [img_logo, img_logo_gray, img_logo_mask, img_logo_mask1, img_roi, img_res0, img_res1, img_res2]
    for x in xrange(len(imgs)):
        plt.subplot(241 + x), plt.imshow(img_convert(imgs[x]), cmap='gray'), plt.title(titles[x])  # , plt.axis('off')
    plt.show()

    # 显示图片,调用matplotlib展示
    plt.figure()
    plt.subplot(332), plt.imshow(img_convert(img_res2), cmap='gray'), plt.title("img_res2")
    plt.subplot(323), plt.imshow(img_convert(img_res0), cmap='gray'), plt.title("img_res0")
    plt.subplot(324), plt.imshow(img_convert(img_res1), cmap='gray'), plt.title("img_res1")
    plt.subplot(3, 4, 9), plt.imshow(img_convert(img_roi), cmap='gray'), plt.title("img_roi")
    plt.subplot(3, 4, 10), plt.imshow(img_convert(img_logo_mask), cmap='gray'), plt.title("img_logo_mask")
    plt.subplot(3, 4, 11), plt.imshow(img_convert(img_logo), cmap='gray'), plt.title("img_logo")
    plt.subplot(3, 4, 12), plt.imshow(img_convert(img_logo_mask1), cmap='gray'), plt.title("img_logo_mask1")
    plt.show()


# cv2与matplotlib的图像转换,cv2是bgr格式,matplotlib是rgb格式
def img_convert(cv2_img):
    # 灰度图片直接返回
    if len(cv2_img.shape) == 2:
        return cv2_img
    # 3通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 3:
        b, g, r = cv2.split(cv2_img)
        return cv2.merge((r, g, b))
    # 4通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 4:
        b, g, r, a = cv2.split(cv2_img)
        return cv2.merge((r, g, b, a))
    # 未知图片格式
    else:
        return cv2_img


# 主函数
if __name__ == "__main__":
    img_deal()

6,参考页面

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容