程序流程:



1.图像采集

先从opencv(2.4.10版本)采集回来摄像头的图像,是一帧一帧的

每一帧图像是一个矩阵,opencv中的mat 数据结构。

2.人脸的美化

人脸美化,我们用的皮肤检测,皮肤在颜色空间是特定的一个区域

检测到这个区域(感兴趣区域),完后对这个区域进行美化,就是滤波,主要是双边滤波和高斯滤波。

3.视频格式转换以及编码

处理好的矩阵颜色空间是rgb的,需要转换成yuv,yuv的颜色空间就是可以播放的,类似我们电视上面看的画面,编码就是传输时候需要发送流,只个流相当于针对数据的压缩,将yuv格式的视频帧编码成h264的格式

Rgb转换成yuv,opencv实现(美颜在这一步实现)

Yuv转换成h264,x264实现

H264转换成rtmp流,libxrtmp实现

4.发送给服务器进行直播

H264的流一般就可以播放了,但是针对目前的网络直播主要是将h264转换成rtmp流,用rtmp的服务器进行播放,这块我们主要用的是adobe media server 5这个服务器进行接受工作

5.技术难点

1.将人脸美化转换为皮肤检测

2.各种编码的转换

3.缓冲区的控制,这块是一个读者写着模型

实现效果:

部分代码:

#include "stdafx.h"
#include "live_beautiful_camera_streaming.h"
#include "CircleBuffer.h" using namespace std;
using namespace cv;
#define GOLABLE_BUFFER_SIZE 1024*64 CPs_CircleBuffer* m_pCircleBuffer; void CameraToH264(void *pcn)
{ CvCapture* capture;
//VideoCapture capture;
Mat frame; //-- 1. Load the cascades
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return ; };
//if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; }; VideoCapture cap(0); //打开默认的摄像头号
if(!cap.isOpened()) //检测是否打开成功
return ; int w = cap.get(CV_CAP_PROP_FRAME_WIDTH);
int h = cap.get(CV_CAP_PROP_FRAME_HEIGHT); int yuv_bufLen = w*h*3/2;
unsigned char* pYuvBuf = new unsigned char[yuv_bufLen]; int index = 0;/// for(;;)
{
Mat frame;
cap >> frame; // 从摄像头中获取新的一帧
//detectAndDisplay( frame );
imshow("original image", frame);
//按esc推出
if(waitKey(40) == 27) break;
//detectAndenhance(frame);
//imshow("enhance image",equalizeIntensityHist(frame));
Mat temp;
//SkinRGB(&IplImage(frame),&IplImage(temp));
//highlight(frame);
MySkinEnhance(frame); /////////////////////////////////////////
cv::Mat yuvImg;
cv::cvtColor(frame, yuvImg, CV_BGR2YUV_I420);
memcpy(pYuvBuf, yuvImg.data, yuv_bufLen*sizeof(unsigned char));
MyOneFrameYuvtoH264(w,h,(char *)pYuvBuf); }
//摄像头会在VideoCapture的析构函数中释放
waitKey(0); delete[] pYuvBuf;
} void H264ToRtmp(void *pcn)
{
Sleep(3000);
My_SendH264To_Rtmp(); } /**
* @function main
*/
int main( void )
{
m_pCircleBuffer = new CPs_CircleBuffer(GOLABLE_BUFFER_SIZE); HANDLE h_cameraToh264;
h_cameraToh264 = (HANDLE)_beginthread((void(__cdecl *)(void *))CameraToH264,0,(void *)1); HANDLE h_h264ToRtmp;
h_h264ToRtmp = (HANDLE)_beginthread((void(__cdecl *)(void *))H264ToRtmp,0,(void *)1); WaitForSingleObject(h_cameraToh264,INFINITE);
WaitForSingleObject(h_h264ToRtmp,INFINITE); Sleep(100);
return 0;
}

---------------------------------后续更新,20160506-------------------------------------------------------------------------------------------------------

该程序的性能跟美颜处理的算法效果息息相关,最近发现了一个联合双边滤波器,有时间 的话集成上去效果应该不错,下面是介绍:

这十年来,在图像处理领域提出了很多新的图像分析和处理方法,包括是自动的以及一些需要有人工参与的,典型的比如stereo depth computations、image colorization、tone mapping of high dynamic range (HDR) images、 graph cuts ,这些算法都有着比较好的效果,但都普遍存在一个问题:就是计算量特别大,很难满足用户的需求。而数字图像在尺寸大小上的增长速度这段时间也相当惊人。还有个问题就是有些算法需要解一个很大的稀疏矩阵方程,可能会大到系统的无法为接其过程分配足够的内存。因此,如果解决这两个问题,一个直观而又简单的想法就是:先处理原图下采样的小图,然后将处理后的结果在上采样。

但是,如此处理存在的问题就是上采样算法会直接影响到处理效果。如果是纯粹的最近邻插值、或者是双线性,抑或是三次立方等复杂点插值算法,都会使人感到效果失真。但是在这种情况下的我们实际上比简单的图像放大时多了一个信息的,就是我有原始的未做处理的并且未缩小的图像的信息,是否能利用这个信息来增强上采样的效果呢?目前我看到了两种这方面的算法。

一种就是联合双边滤波 :http://www.cnblogs.com/Imageshop/p/3677313.html

参考文献:

Adobe Flash Media Server 5.0.3
官方中文版:(下载地址和说明)

http://www.launchdigital.net/supportview.asp?bid=98&Sid=124&id=594

http://www.xdowns.com/soft/1/71/2014/Soft_116532.html

关于美颜 摄像头功能的部分说明:

http://blog.csdn.net/wangyaninglm/article/details/50806051

yuv格式编码为h264:

http://blog.csdn.net/leixiaohua1020/article/details/42078645

h264发送rtmp流:

http://www.cnblogs.com/haibindev/archive/2012/04/16/2450989.html

http://blog.csdn.net/leixiaohua1020/article/details/42105049

Adobe Flash Media Server 5.0.3
官方中文版:(下载地址和说明)

http://www.launchdigital.net/supportview.asp?bid=98&Sid=124&id=594

http://www.xdowns.com/soft/1/71/2014/Soft_116532.html

关于美颜 摄像头功能的部分说明:

http://blog.csdn.net/wangyaninglm/article/details/50806051

yuv格式编码为h264:

http://blog.csdn.net/leixiaohua1020/article/details/42078645

h264发送rtmp流:

http://www.cnblogs.com/haibindev/archive/2012/04/16/2450989.html

http://blog.csdn.net/leixiaohua1020/article/details/42105049

环形缓冲区实现:http://blog.csdn.net/lezhiyong/article/details/7879558

完整代码下载:http://download.csdn.net/detail/wangyaninglm/9480783

github地址:https://github.com/wynshiter/live_beautiful_camera_streaming

基于OpenCV 的美颜相机推送直播流的更多相关文章

  1. ffmpeg推送直播流的技术进展

    首先安装好NGINX并打开服务 然后安装好ffmpeg 然后参考:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=2879051 ...

  2. 基于Node.js的实时推送 juggernaut

    基于Node.js的实时推送 juggernaut Juggernaut 基于 Node.js 构建.为浏览器和服务器端提供一个实时的连接,可在客户端和服务器端进行数据的实时推送,适合多角色游戏.聊天 ...

  3. 基于B/S模式的推送

    基于B/S模式的推送 https://www.ibm.com/developerworks/cn/web/wa-lo-comet/ 传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.这 ...

  4. Android消息推送(二)--基于MQTT协议实现的推送功能

    国内的Android设备,不能稳定的使用Google GCM(Google Cloud Messageing)消息推送服务. 1. 国内的Android设备,基本上从操作系统底层开始就去掉了Googl ...

  5. Android 基于Netty接收和发送推送解决方案的消息字符串(三)

    在上一篇文章中<Android 基于Netty的消息推送方案之概念和工作原理(二)> .我们介绍过一些关于Netty的概念和工作原理的内容,今天我们先来介绍一个叫做ChannelBuffe ...

  6. 基于 WebSocket 的 MQTT 移动推送方案

    WebSphere MQ Telemetry Transport 简介 WebSphere MQ Telemetry Transport (MQTT) 是一项异步消息传输协议,是 IBM 在分析了他们 ...

  7. 基于C++ 苹果apns消息推送实现(2)

    1.该模块的用途C++ 和 Openssl 代码 它实现了一个简单的apns顾客 2.配套文件:基于boost 的苹果apns消息推送实现(1) 3.最初使用的sslv23/sslv2/sslv3仅仅 ...

  8. EasyRTMP实现对接海康、大华等IPCamera SDK进行RTMP推送直播功能

    本文转自EasyDarwin团队Kim的博客:http://blog.csdn.net/jinlong0603 Demo项目介绍 EasyRTMP Demo代码下载地址https://github.c ...

  9. EasyDarwin开源流媒体服务器如何实现按需推送直播的

    --本文转自EasyDarwin开源团队成员邵帅的博客:http://blog.csdn.net/ss00_2012/article/details/51441753 我们使用EasyDarwin的推 ...

随机推荐

  1. ●CodeForces 549F Yura and Developers

    题链: http://codeforces.com/problemset/problem/549/F题解: 分治,链表. 考虑对于一个区间[L,R],其最大值在p位置, 那么答案的贡献就可以分为3部分 ...

  2. bzoj2096[Poi2010]Pilots 单调队列

    2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 983  Solved: 513[Submit][Statu ...

  3. [APIO/ctsc2007]

    A.风铃 给一棵二叉树,叶子结点是玩具,为使你的弟弟满意,你需要选一个满足下面两个条件的风铃: (1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是一样的)或至多相差一层.(2) ...

  4. HashMap实现原理和源码解析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构.许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中的对应实现HashMap的 ...

  5. 一口一口吃掉Hibernate(四)——多对一单向关联映射

    hibernate对于数据库的操作,全部利用面向对象的思维来理解和实现的.一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它. 今天就 ...

  6. Uncaught RangeError: Maximum call stack size exceeded-栈溢出

    在看函数的arguments对象的时候,用了arguments.callee写了一个递归. 当执行函数func(99999)时候,直接报错了,一看,原来栈溢出了. 当执行递归运算的时候,忘记加点判断条 ...

  7. SpringMVC注解@Component、@Repository、@Service、@Controller区别

    SpringMVC中四个基本注解: @Component.@Repository   @Service.@Controller 看字面含义,很容易却别出其中三个: @Controller   控制层, ...

  8. Java为什么要配置环境变量及如何配置环境变量

    在没有配置环境变量之前,用cmd执行Java文件,需要指明Java的可执行文件,否则无法运行. 配置环境是为了在不用切换可执行文件目录下,方便Java程序的执行和控制. 那么环境变量就是让系统根据环境 ...

  9. Docker常见仓库MongoDB

    MongoDB 基本信息 MongoDB 是开源的 NoSQL 数据库实现. 该仓库提供了 MongoDB 2.2 ~ 2.7 各个版本的镜像. 使用方法 默认会在 27017 端口启动数据库. $ ...

  10. 从输入url到页面返回到底发生了什么

    1. 前言 Google应该是开发者平日里用得最多的网站之一,今早笔者在浏览器地址栏里键入www.google.com的时候,突然想了解下这背后的网络通信过程究竟是怎么样的.毕竟自己也算是一名Web开 ...