写点什么

喂~ 办章吗?Python OpenCV 互联网 + 项目,图像处理取经之旅第 18 天

发布于: 2021 年 04 月 04 日
喂~ 办章吗?Python OpenCV 互联网+ 项目,图像处理取经之旅第 18 天

今天学习的目标依旧是研究图像的合成,重点还是在 ROI 与掩膜相关知识


本文的最终目标,把下面这个章扣在任意图片上,当然你可以把这个章更换成任意的,例如发票章。



PNG 图片相关通道说明

读取图片比较简单,直接进行操作即可,重点注意 imread 中第三个参数即可。


# 读取图片def read_img(path):    img = cv.imread(path,-1)    print(img.shape)    dst = cv.resize(img,(130,124))    cv.imshow("img", dst)
if __name__ == "__main__": # png 透明图片路径 path = r"./18_png.png" read_img(path)
cv.waitKey() cv.destroyAllWindows()
复制代码


下面的步骤是将 PNG 图片,透明部分修改为黑色。


def alpha2black_opencv2(img):    width,height,channels = img.shape    for yh in range(height):        for xw in range(width):            color_d = img[xw, yh]            # 找到alpha通道为 0 的像素            if(color_d[3] == 0):                # 改变像素颜色为黑色                img[xw, yh] = [0, 0, 0, 0]    # 返回一个不透明的BGR图片    return cv.cvtColor(img, cv.COLOR_BGRA2BGR)
复制代码


循环每一个像素点,当发现 alpha 通道为 0 的时候,就修改该点像素为 [0,0,0,0]。


这里要注意的是 png 图片每个像素点的颜色为 [ 76 112 71 0] 格式,其中最后一个值表示 alpha 通道值。


该通道透明部分都为 0,所以修改该值即可。


运行效果截图:



如果你还有疑问,可以这样进行测试。


获取任意透明部分的像素颜色值,或者获取任意有颜色部分像素值。


透明部分的值为:[ 76 112 71 0]非透明部分的值为:[ 0 0 255 255]


那 alpha 部分有其他值吗?肯定存在呀,这个是透明度,可以做如下尝试,就拿本案例提供的图片来说


当 alpha 通道为 255 的时候,我们将其调整为 100,看一下对比效果。


def alpha2black_opencv2(img):    width, height, channels = img.shape    print(img[50, 30])    print(img[50, 30][0])    for yh in range(height):        for xw in range(width):            color_d = img[xw, yh]            if(color_d[3] == 255):                img[xw, yh, 3] = 100    print(img[62, 62])    print(img[62, 62][0])    # 返回一个不透明的BGR图片    print(img.shape)    cv.imwrite("./1.png", img)    return img    # return cv.cvtColor(img, cv.COLOR_BGRA2BGR)
复制代码


注意上述代码在运行之后,不要通过 cv.imshow() 展示,要通过 cv.imwrite() 写入到文件中,才可查看效果。


加载待盖章图片

加载背景图,并且在背景图上找到 ROI 区域。


先整理逻辑,一会在查看代码:


第一步:找到目标 ROI 区域,这个区域要和印章图片大小一致,不一致无法进行图片相加操作第二步:在目标区域中把印章红色区域抠出来,采用任何方式都可以,但是要把印章红色区域全部置为黑色第三步:将印章图片与第二步合成的图片进行二次相加操作,因为在第二步已经将印章区域像素值设置为 0,所以在于印章合并的时候,黑色区域会显示成印章第四步:将合成好的图片还原回去。


最终完整呈现的代码如下:


import cv2 as cv
def alpha2black_opencv2(img): width, height, channels = img.shape
for yh in range(height): for xw in range(width): color_d = img[xw, yh] if(color_d[3] == 0): img[xw, yh] = [0, 0, 0, 0]
return cv.cvtColor(img, cv.COLOR_BGRA2BGR)
# 读取图片def read_img(path): img = cv.imread(path, -1) print(img.shape)
dst = cv.resize(img, (130, 124)) # cv.imshow("img", dst) # 接下来将 png 透明部分处理成黑色 ret = alpha2black_opencv2(dst) # cv.imshow("ret", ret)
# 加载背景图 bg = cv.imread("./bg.jpeg") # 获取目标 roi roi = bg[300:424, 400:530] # cv.imshow("roi",roi) # 将印章与roi进行叠加 mask = cv.cvtColor(ret, cv.COLOR_BGR2GRAY)
# 想要得到红色印章和背景融合的图 # 获取印章的二值化图像,红色印章为纯白色 thresh, new_mask = cv.threshold(mask, 10, 255, cv.THRESH_BINARY)
# 获取反向图 mask_inv = cv.bitwise_not(new_mask) # cv.imshow("mask_inv",mask_inv) # 第一步:在原图中抠出印章区域,即印章区域为黑色 new_img = cv.add(roi, 1, mask = mask_inv) # cv.imshow("new_img", new_img) # 第二步,将抠出印章区域得到的图片与印章相加,获取到合成图 replace_img = cv.add(new_img,ret) print(replace_img.shape) # cv.imshow("bg", bg) # 第三步,将合成好的图片,送回到原图 bg[300:424, 400:530] = replace_img cv.imshow("bg",bg)

if __name__ == "__main__": # png 透明图片路径 path = r"./18_png.png" read_img(path)
cv.waitKey() cv.destroyAllWindows()
复制代码


两张单独的图片如下:



合成之后的效果图如下,整体效果满意,但是还是存在黑边,接下来我们还是继续研究这个东东,下篇博客见。



OpenCV 尾声

1 个小时又过去了,对 Python OpenCV 相关的知识点,你掌握了吗?


空闲之余,可以订阅橡皮擦的爬虫百例课程学习爬虫知识。


想学 Python 爬虫,可以订阅橡皮擦专栏哦~ 🈲🈲🈲🈲 点击发现惊喜 🈲🈲🈲🈲




今天是持续写作的第 <font color="red">57</font> / 100 天。如果你有想要交流的想法、技术,欢迎在评论区留言。




如果你想跟博主建立亲密关系,可以关注同名公众号 <font color="red">梦想橡皮擦</font>,近距离接触一个逗趣的互联网高级网虫。博主 ID:梦想橡皮擦,希望大家<font color="red">点赞</font>、<font color="red">评论</font>、<font color="red">收藏</font>。

发布于: 2021 年 04 月 04 日阅读数: 11
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
喂~ 办章吗?Python OpenCV 互联网+ 项目,图像处理取经之旅第 18 天