阅读 537

Python使用指南(一):在微信头像上添加红旗贴画

指南声明

《Python使用指南》系列文章基于我的Python学习过程总结而成,主要内容是对各个实际需求从需求分析到使用Python进行实现的全幅记录。由于技术和语文水平有限,该指南可能存在各种技术或表达问题,欢迎你留言进行讨论。

本指南系列文章一般分为以下四部分:

  • 开发环境
  • 需求分析
  • 相关知识
  • 代码实现

其中,开发环境部分会因为需求不同而发生改变,在你尝试运行相应文章的代码时请注意你的开发环境是否与文章开发环境相匹配或兼容。

此外,本指南所涉及的Python代码实现存档于Python-User-Guide仓库,欢迎大家前去Star。

开发环境

基础环境

  • OS:Window 10

  • Python:Python 3.7.4-64bit

  • IDE:JetBrains PyCharm 2019.2.2 x64

使用的第三方库

  • opencv-python-4.1.1.26

  • opencv-contrib-python-4.1.1.26

  • numpy-1.17.2

需求分析

本篇文章的需求是在微信头像上添加红旗贴画,这一需求来自最近很火的@微信官方给自己的微信头像添加红旗贴画。

该需求涉及到对使用Python对图像进行各种操作,那么需要了解的知识有以下两个方面:

  • 数字图像处理基础知识
  • Python图像处理库的安装和使用

在经过一系列的Google搜索后,将我对于这两方面的了解总结于下面相关知识部分。

相关知识

数字图像处理

数字图像都是由像素构成。在一张数字图像中,每个像素都有明确的位置和被分配的色彩数值。

常见的数字图像有灰度图像和RGB图像,其中灰度图像主要用于进行一些高阶图像处理操作,在本片文章中不涉及相关知识,故不加以赘述。

以常见的RGB图像为例,一张RGB图像可以被理解为一个多维矩阵,每个像素点为一个矩阵元素,像素点本身又是一个包含R(Red)、G(Green)、B(Blue)三色数值的向量。在计算机中,任何颜色都可由红、绿、蓝三原色叠加而成,用数字图像处理领域相关术语描述则分别是R通道、G通道、B通道,在后面进行图像处理时这三个通道会被经常用到。

Python图像处理库

本篇文章中选择的Python数字图像处理库是OpenCV,选择的原因是Google搜索使用Python进行图像处理时看到的第一页搜索结果都是它,所以你也可以使用Pillow等图像处理库,在基本功能功能和调用API上都差不多。

需要注意的是,在使用OpenCV时,需配套安装numpy库,这是因为opencv-python依赖于numpy进行矩阵数值处理。

安装opencv及numpy

打开Pycharm->File->Settings->Project Interpreter,点击+,如下图:

搜索opencv-pythonopencv-contrib-python安装OpenCV库及其扩展:

搜索numpy安装numpy库:

基本使用

导入cv模块

import cv2 as cv
import numpy as np
复制代码

加载图像并显示

src = cv.imread("head.jpg")
cv.namedWindow("head", cv.WINDOW_AUTOSIZE)
cv.imshow("head", src)
cv.waitKey(0)
cv.destroyAllWindows()
复制代码

查看图像基本参数

print(src.shape)
# 输出:高,宽,通道数
(460,460,3)
复制代码

放大、缩小图像

h, w, c = src.shape
dst = cv.resize(src, (h//2, w//2))
cv.imshow("resize-image", dst)
复制代码

代码实现

import cv2 as cv

class AddFlag():
    def __init__(self, head_img, flag_img):
        self.head_img = head_img
        self.flag_img = flag_img

    def add_flag(self):
        try:
            head_img = self.head_img
            flag_img = self.flag_img

            # 读取头像和红旗贴画
            img_head = cv.imread(head_img)
            img_flag = cv.imread(flag_img)

            # 获取头像和红旗贴画宽度
            w_head, h_head = img_head.shape[:2]
            w_flag, h_flag = img_flag.shape[:2]

            # 计算红旗贴画缩放比例
            scale = w_head / w_flag / 4
            # 缩放图案
            img_flag = cv.resize(img_flag, (0, 0), fx=scale, fy=scale)
            # 获取缩放后的红旗贴画宽高
            w_flag, h_flag = img_flag.shape[:2]

            # 按3个通道合并图片
            for c in range(0, 3):
                img_head[w_head - w_flag:, h_head - h_flag:, c] = img_flag[:, :, c]

            # 保存最终结果
            cv.imwrite('head_flag.jpg', img_head)
            return 'success'
        except Exception as e:
            print('ERROR: ' + e)


head_img = AddFlag('head.jpg', 'flag.png')
head_img.add_flag()
复制代码

最终效果

相关代码和资源见Python-User-Guide/0x01

关注下面的标签,发现更多相似文章
评论