RPi-OpenCV_10行代码为你的头像添加国旗


在学完前面较为枯燥的概念后,接下来,是时候展现真正的技术了。由于OpenCV既是机器视觉库,也是图像处理库,给头像添加国旗,那自然是小菜一碟,如果用Python写的话,只要10行左右。

1 思路分析

好比把大象装进冰箱要几步一样,为头像添加上国旗也是如此,先不讲通过什么语言实现,毕竟语言只是工具,OK,如果那,那为头像添加上国旗则需要以下几个步骤:

  • Step1:读取头像和国旗图案。
  • Step2:把国旗叠加到头像上。
  • Step3:把叠加后的图片保存。

把大象放进冰箱只要这么几步,但是具体把国旗叠加到头像上,需要考虑的一体细节:

  • 国旗必须缩放到合适大小,才能放到头像上。
  • 国旗缩放后不能变形。
    因此:

    就把国旗的宽度缩放至头像宽度的1/4,然后高度也按照同样的比例进行缩放。

核心问题已经解决了,剩下来就是工具自身实现的问题,在OpenCV中,读写图像,缩放图像,图像合成,图像显示,是比较基本的操作,现在,就开始驾驭工具,把大象放入冰箱,先从Python开始讲起:

2 Python实现

# -*- coding: utf8 -*-
import cv2

# Step1:读取头像和国旗图像。
img_head = cv2.imread('head.jpg')
img_flag = cv2.imread('flag.jpg')

# Step2:把国旗叠加到头像上。
# Step2.1:获取头像和国旗宽度
w_head, h_head = img_head.shape[:2]
w_flag, h_flag = img_flag.shape[:2]
# Step2.2:根据宽度计算缩放比例
scale = w_head / w_flag / 4
# Step2.3:根据缩放比例缩放国旗
img_flag = cv2.resize(img_flag, (0, 0), fx=scale, fy=scale)
# Step2.4:获取缩放后国旗的新尺寸
w_flag, h_flag = img_flag.shape[:2]
# Step2.5:根据缩放后的尺寸叠加国旗到头像右下角
for c in range(0, 3):
    img_head[w_head - w_flag:, h_head - h_flag:, c] = img_flag[:, :, c]

# Step3:保存叠加后的图像
cv2.imwrite('new_head.jpg', img_head)

程序执行效果如下图所示:

注释有说明步骤相关的思路及其实现。

3 cpp实现

接下来,来看看cpp执行相关的代码

#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

int main()
{
    //Step1:读取头像和国旗图像。
    Mat img_head = imread("head.jpg");
    Mat img_flag = imread("flag.jpg");
    Mat img_flag_resized;

    //Step2:把国旗叠加到头像上。
    //Step2.1:获取头像和国旗宽度
    int w_head = img_head.cols;
    int h_head = img_head.rows;
    int w_flag = img_flag.cols;
    int h_flag = img_flag.rows;
    //Step2.2:根据宽度计算缩放比例
    double scale = (double)w_head/w_flag/4;
    //Step2.3:根据缩放比例缩放国旗    
    resize(img_flag,img_flag_resized,Size(),scale,scale,INTER_NEAREST);
    //Step2.4:获取缩放后国旗的新尺寸
    w_flag = img_flag_resized.cols;
    h_flag = img_flag_resized.rows;
    //Step2.5:根据缩放后的尺寸叠加国旗到头像右下角
    Mat imageROI=img_head(Rect(w_head-w_flag,h_head-h_flag,w_flag,h_flag));
    img_flag_resized.copyTo(imageROI);

    //Step3:保存叠加后的图像
    imwrite("new_head.jpg",img_head);
    return 0;
}

其CmakeList.txt为:

cmake_minimum_required(VERSION 3.0)
project(07_National_Flag)
find_package(OpenCV REQUIRED)
add_executable(07_National_Flag main.cpp)
target_link_libraries(07_National_Flag ${OpenCV_LIBS})

执行结果图下图所示:

其执行效果同Python。


Author: Ruimin Huang
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Ruimin Huang !
  TOC