图片处理——基于openCV实现美颜相机_徐福记456的博客-程序员ITS203_opencv美颜相机

技术标签: 美颜相机  宠萌妆饰  图片处理  人脸识别  

        今天是2017年最后一晚,希望大家元旦前夕玩得开心,准备迎接2018全新的一年,活出程序员的态度。

        最近发现有些女孩在朋友圈发的自拍照肤白貌美,甚至头上魔幻般地长出猫耳朵、猫鼻子、猫胡须,各种调皮搞怪。这一切归功于程序员们不懈努力,推动科技发展,最终科技提高生活品质。美颜相机、美妆相机、秒拍、天天P图们让自拍更加精彩,带有滤镜、美颜、宠萌等各种效果。讲真的,一开始我比较好奇的是宠萌效果,认真分析后总结出实现过程经过三个步骤:人脸检测——>计算放置位置——>绘制宠萌图标。按照国际惯例,先看下图片效果:


        其实,最关键是第一步:人脸检测。这里采用openCV开源库实现(如果不了解openCV这个计算机视觉开源库的,可以去官网学习:https://opencv.org/),先把openCVLibrary集成到项目里,使用训练好的haarcascade模型来初始化Detector,在摄像头每帧预览数据回调时,对图片区域搜索式扫描进行人脸检测。需要注意的是,Android使用的是Bitmap,而openCV使用的是Mat,两者需要进行转换。关键代码如下:

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();
        // 检测人脸
        Rect[] object = mFaceDetector.detectObject(mGray, mObject);
        if(object != null && object.length > 0){
            //检测到人脸矩形
            Rect rect = object[0];
            //矩形标识
//            Imgproc.rectangle(mRgba, rect.tl(), rect.br(), mFaceDetector.getRectColor(), 3);
            if(beauty != null){
                //添加宠萌妆饰
                addBeauty((int)rect.tl().y, (int)(rect.tl().x+rect.br().x-beauty.cols())/2);
            }
        }
        //拍照一帧数据回调
        if(onPhotoTakenListener != null){
            onPhotoTakenListener.onPhotoTaken(mRgba);
        }
        return mRgba;
    }

        在检测到人脸后,得到人脸在图片的矩形位置,然后计算出宠萌特效放置的位置,y轴坐标为矩形的top,x轴坐标为(矩形left+矩形right-beauty宽度)/2。接着绘制图标:

    /**
     * 添加宠萌效果
     * @param offsetX x坐标偏移量
     * @param offsetY y坐标偏移量
     */
    private void addBeauty(int offsetX, int offsetY){
        offsetX -= 200;//高度校正
        if(offsetX < 0){
            offsetX = 0;
        }
        for (int x=0; x<beauty.rows(); x++){
            for (int y=0; y<beauty.cols(); y++){
                double[] array = beauty.get(x, y);
                if(array[0] != 0) {//过滤全黑像素
                    mRgba.put(x+offsetX, y+offsetY, array);
                }
            }
        }
    }
    /**
     * 获取宠萌妆饰list集合
     */
    private void getBeauty(){
        Drawable drawable1 = getResources().getDrawable(R.drawable.cat, null);
        Bitmap bitmap1 = ((BitmapDrawable) drawable1).getBitmap();
        bitmap1 = Bitmap.createScaledBitmap(bitmap1, 320, 320, true);
        Mat beauty1 = new Mat();
        Utils.bitmapToMat(bitmap1, beauty1);
        beautyList.add(beauty1);
        Drawable drawable2 = getResources().getDrawable(R.drawable.rabbit, null);
        Bitmap bitmap2 = ((BitmapDrawable) drawable2).getBitmap();
        bitmap2 = Bitmap.createScaledBitmap(bitmap2, 320, 320, true);
        Mat beauty2 = new Mat();
        Utils.bitmapToMat(bitmap2, beauty2);
        beautyList.add(beauty2);
    }
        在拍照时,回调数据格式是Mat,需要先转成Bitmap,然后保存图片:
    /**
     * 保存图片
     * @param frameData 帧数据
     */
    private void savePicture(Mat frameData){
        Bitmap bitmap = Bitmap.createBitmap(frameData.width(), frameData.height(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(frameData, bitmap);
        String fileName = PATH + File.separator + dataFormat.format(new Date(System.currentTimeMillis())) + ".jpg";
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(fileName);
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
        如果觉得静态图片的宠萌效果不够酷,那么来看下拍照预览的动态效果(GIF图处理比较模糊,大家勿喷):

        备注:人脸检测部分参考http://blog.csdn.net/q4878802/article/details/51841793

        接下来我会继续研究美颜、滤镜、抠图。欢迎热爱图片处理与多媒体开发的同行朋友相互交流,互相学习。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011686167/article/details/78943824

智能推荐

分布式任务调度平台之 xxl-job配置部署_Mynah886的博客-程序员ITS203_xxl-job单台部署

目录导航一、xxl-job安装部署 二、openapi配置 三、BEAN模式开发 四、操作指南 五、xxl-job实现高可用 六、xxl-job高可用测试一、xxl-job安装部署1.数据库创建脚本CREATE database if NOT EXISTS `xxl_job` default character set utf8 collate utf8_general_...

linux下qt实现vlc视频播放器,Qt封装本地视频播放器(VLC二次开发)_乖巧是我姓名的博客-程序员ITS203

Qt本地视频播放器1、使用vlc官方sdk封装,并在QLabel上面播放2、首先到vlc官网下载vlc的sdk环境,下载地址:http://download.videolan.org/pub/videolan/vlc/. (1)、选择last最近版本: (2)、选择win32版本,根据你自己安装的qt版本来下载: (3)、最后选win32.7z下载就好了 3、接下来设置好qt使用第三方库的配...

【cookbook pandas】学习笔记 chap 11. Combining Pandas Objects_萝卜丝皮尔的博客-程序员ITS203_pandas loc cannot join with no overlapping index n

Introductiona wide variety of options are available to combine two or more DataFrame or Series together;the append method is the least flexibility and only allows for new rows to be appended to a DataFrame.the concat method is very versatile and can com

酒店管理系统需求分析_哈652的博客-程序员ITS203_酒店管理系统需求分析

一、系统概述1.1背景随着计算机技术的飞速发展,信息时代的到来,信息改变了我们社会,各类行业在日常经营管理方面也悄悄的走向规范化和网络化,酒店业作为一个前景广阔同时又竞争激烈的行业,它的内容对于经营的决策者和管理者来说都至关重要。改革开放以来,我国的酒店业务迅速发展,已经成为一个具有相当规模的产业。在以前,酒店客房管理使用手工处理账务,存在许多现金流失的漏洞、处理效率低、保密性差。因此,想要使酒店的工作质量和效率准确提高,采用先进的计算机网络通信技术来改变酒店业务模式,实现酒店业务管理的自动化已经成为一

general BSD socket_星空探索的博客-程序员ITS203_cgeneralsocket

/** *  struct socket - general BSD socket *  @state: socket state (%SS_CONNECTED, etc) *  @type: socket type (%SOCK_STREAM, etc) *  @flags: socket flags (%SOCK_NOSPACE, etc) *  @ops: protoco

A. Oh Those Palindromes(思维结论题)_少侠,慢点走的博客-程序员ITS203

题意:给一个字符串,让你重新把字符串重新排,使他从左到右把他顺便分成子串,让他可以成回文的子串最多;思路:当然是按升序排最多回文结论题。考虑个连在一起,此时有 个回文子串。再在其中插入一个其它的字符,答案一定会变小。因为此时把原串拆成了两部分。那么sort一遍就好了#include&lt;bits/stdc++.h&gt;using namespace std;typedef ...

随便推点

《机器学习技法》学习笔记15——矩阵分解_小爷毛毛(卓寿杰)的博客-程序员ITS203

http://blog.csdn.net/u011239443/article/details/76735871线性网络模型Netflix在2006年给出了一个数据集 (用户id,电影id,电影评分) 让我们来预测用户未评分的电影评分分数。 我们可以讲用户id进行二分向量编码,然后同意用户的电影评分组成一个向量,即得到:因为向量x只有一个值为1,所以模型可以变成:而对于某一个电影的预测评分可以

windows 系统在vs2010 中配置libxml2,及读取xml代码例子_能量守恒洛的博客-程序员ITS203

windows 系统在vs2010 中配置libxml2,及读取xml代码例子 ,用到了的文件包括zlib-1.2.3.win32,iconv-1.9.2.win32 ,libxml2-2.7.6.win32文件

lsof u mysql wc l_linux常用命令之lsof 、netstat、ipcs、ldd_我爱学习2018的博客-程序员ITS203

一、lsoflsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。每行显示一个打开的文件,若不指定条件默认将显示所有进程打开的所有文件。lsof输出各列信息的意义如下:#COMMAND:进程的名称#PID:进程标识符#USER:进程所有者#FD:文件描述符,应用程序通过文...

将数组A中的内容和数组B中的内容进行交换。(数组一样大)_Angus_lxy的博客-程序员ITS203_将数组a与数组b互换

问题描述:将数组A中的内容和数组B中的内容进行交换。(数组一样大)问题分析:数组内容交换实质上与两个数进行交换一样,方法可以用很多种,这里我只用两种办法来解决这类问题,其他方法可参考之前写的博客,这里将链接附上:https://blog.csdn.net/lexiaoyao_0000/article/details/90116017方法一:采用中间变量法tmp = a[i]...

kafka查看broker上主副本_kafka入门之broker-副本与ISR设计_谭亭的博客-程序员ITS203

kafka把分区的所有副本均匀地分配到所有broker上,并从这些副本中挑选一个作为leader副本对外提供服务,而其他副本被称为follower副本,只能被动地向leader副本请求数据,从而保持与leader副本的同步:所谓isr,就是Kafka集群动态维护的一组同步副本集合,每个topic分区都有自己的isr列表,isr中的所有副本都与leader保持同步状态,而producer写入的一条K...

5G NR标准 第2章 5G标准化_sundaygeek的博客-程序员ITS203

5G NR标准 第2章 5G标准化移动通信系统的研究,开发,实施和部署是由无线行业在国际协调一致的努力下完成的,通过该协议,人们共同商定了定义完整的移动通信系统的通用行业规范。 这项工作在很大程度上取决于全球和区域法规,特别是对于频谱使用而言,频谱使用是所有无线电技术的基本组成部分。 本章描述了对于定义移动通信系统至关重要的监管和标准化环境。2.1 标准化和监管概述有许多组织参与创建技术规范和标准以及移动通信领域的法规。 这些可以大致分为三类:标准化组织,监管机构以及产业论坛。标准化组织(SDO)

推荐文章

热门文章

相关标签