立即注册 找回密码

微雪课堂

搜索
微雪课堂 树莓派 树莓派OpenCV教程 查看内容

树莓派OpenCV系列教程6:10行代码添加国旗

2019-10-29 09:31| 发布者: Tornado| 查看: 1516| 评论: 3

摘要: 在学完前面较为枯燥的概念后,接下来,是时候展现真正的技术了。由于OpenCV既是机器视觉库,也是图像处理库,给头像添加国旗,那自然是小菜一碟,如果用Python写的话,只要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 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()
{
    //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。


79

顶一下

刚表态过的朋友 (79 人)

相关阅读

发表评论

最新评论

引用 virtualnode 2019-11-29 14:57
多谢楼主的解释。我也分别试着让它分别输出了这个RGB模式的图像的蓝、绿、红三个通道:)
引用 Tornado 2019-11-28 17:46
可以了解下Numpy中图像数据的存储结构,粗略理解成:一张图像,是一个三维数组,这三维分别是:行,列,页,第一页是B,第二页是G,第三页是R,3就是3页的意思
引用 virtualnode 2019-11-28 15:44
请问楼主能不能解释下这两句是什么意思?特别是这个3是怎么来的?
# Step2.5:根据缩放后的尺寸叠加国旗到头像右下角
for c in range(0, 3):
    img_head[w_head - w_flag:, h_head - h_flag:, c] = img_flag[:, :, c]

查看全部评论(3)

基础入门
OpenCV
littleGL

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2020-12-4 19:26 , Processed in 0.023217 second(s), 18 queries .

返回顶部