在学完前面较为枯燥的概念后,接下来,是时候展现真正的技术了。由于OpenCV既是机器视觉库,也是图像处理库,给头像添加国旗,那自然是小菜一碟,如果用Python写的话,只要10行左右。
1 思路分析
好比把大象装进冰箱要几步一样,为头像添加上国旗也是如此,先不讲通过什么语言实现,毕竟语言只是工具,OK,如果那,那为头像添加上国旗则需要以下几个步骤:
- Step1:读取头像和国旗图案。
- Step2:把国旗叠加到头像上。
- Step3:把叠加后的图片保存。
把大象放进冰箱只要这么几步,但是具体把国旗叠加到头像上,需要考虑的一体细节:
- 国旗必须缩放到合适大小,才能放到头像上。
- 国旗缩放后不能变形。
因此:
就把国旗的宽度缩放至头像宽度的1/4,然后高度也按照同样的比例进行缩放。
核心问题已经解决了,剩下来就是工具自身实现的问题,在OpenCV中,读写图像,缩放图像,图像合成,图像显示,是比较基本的操作,现在,就开始驾驭工具,把大象放入冰箱,先从Python开始讲起:
2 Python实现
import cv2
img_head = cv2.imread('head.jpg')
img_flag = cv2.imread('flag.jpg')
w_head, h_head = img_head.shape[:2]
w_flag, h_flag = img_flag.shape[:2]
scale = w_head / w_flag / 4
img_flag = cv2.resize(img_flag, (0, 0), fx=scale, fy=scale)
w_flag, h_flag = img_flag.shape[:2]
for c in range(0, 3):
img_head[w_head - w_flag:, h_head - h_flag:, c] = img_flag[:, :, c]
cv2.imwrite('new_head.jpg', img_head)
程序执行效果如下图所示:
注释有说明步骤相关的思路及其实现。
3 C++实现
接下来,来看看C++执行相关的代码
#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img_head = imread("head.jpg");
Mat img_flag = imread("flag.jpg");
Mat img_flag_resized;
int w_head = img_head.cols;
int h_head = img_head.rows;
int w_flag = img_flag.cols;
int h_flag = img_flag.rows;
double scale = (double)w_head/w_flag/4;
resize(img_flag,img_flag_resized,Size(),scale,scale,INTER_NEAREST);
w_flag = img_flag_resized.cols;
h_flag = img_flag_resized.rows;
Mat imageROI=img_head(Rect(w_head-w_flag,h_head-h_flag,w_flag,h_flag));
img_flag_resized.copyTo(imageROI);
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。