基于OpenCV 的美颜相机推送直播流
程序流程:
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 的美颜相机推送直播流的更多相关文章
- ffmpeg推送直播流的技术进展
首先安装好NGINX并打开服务 然后安装好ffmpeg 然后参考:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=2879051 ...
- 基于Node.js的实时推送 juggernaut
基于Node.js的实时推送 juggernaut Juggernaut 基于 Node.js 构建.为浏览器和服务器端提供一个实时的连接,可在客户端和服务器端进行数据的实时推送,适合多角色游戏.聊天 ...
- 基于B/S模式的推送
基于B/S模式的推送 https://www.ibm.com/developerworks/cn/web/wa-lo-comet/ 传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.这 ...
- Android消息推送(二)--基于MQTT协议实现的推送功能
国内的Android设备,不能稳定的使用Google GCM(Google Cloud Messageing)消息推送服务. 1. 国内的Android设备,基本上从操作系统底层开始就去掉了Googl ...
- Android 基于Netty接收和发送推送解决方案的消息字符串(三)
在上一篇文章中<Android 基于Netty的消息推送方案之概念和工作原理(二)> .我们介绍过一些关于Netty的概念和工作原理的内容,今天我们先来介绍一个叫做ChannelBuffe ...
- 基于 WebSocket 的 MQTT 移动推送方案
WebSphere MQ Telemetry Transport 简介 WebSphere MQ Telemetry Transport (MQTT) 是一项异步消息传输协议,是 IBM 在分析了他们 ...
- 基于C++ 苹果apns消息推送实现(2)
1.该模块的用途C++ 和 Openssl 代码 它实现了一个简单的apns顾客 2.配套文件:基于boost 的苹果apns消息推送实现(1) 3.最初使用的sslv23/sslv2/sslv3仅仅 ...
- EasyRTMP实现对接海康、大华等IPCamera SDK进行RTMP推送直播功能
本文转自EasyDarwin团队Kim的博客:http://blog.csdn.net/jinlong0603 Demo项目介绍 EasyRTMP Demo代码下载地址https://github.c ...
- EasyDarwin开源流媒体服务器如何实现按需推送直播的
--本文转自EasyDarwin开源团队成员邵帅的博客:http://blog.csdn.net/ss00_2012/article/details/51441753 我们使用EasyDarwin的推 ...
随机推荐
- 【USACO】 录制唱片
题目描述 贝西想从奶牛摇滚乐队的 N 首歌里挑出一些录制一套专辑.专辑分 K 张唱片,每张唱片可容纳总长为 C 分钟的歌曲.第 i 首歌的长度为 T i 分钟,录制唱片时,唱片之间的歌曲需要保持原本的 ...
- 遗传算法:N皇后
N皇后问题描述 N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行.同一列.同一斜线上的皇后都会自动攻击). 遗传算法 遗传算法是局部束搜索的变形: 与自 ...
- VS2012中C++,#include无法打开自己所写的头文件(.h)
最近刚开始学cocos2d-x,创建项目之后,自己按照<cocos2d-x 3.x 游戏开发>的教程写代码 先写了一个头文件 MyHelloWorldScene.h 然后在 AppDe ...
- Jenkins简明入门(一) -- 安装
如今Jenkins官网的Guide里使用了Docker,网上很多Jenkins入门教程都已过时了,所以写这一篇入门教程. 官网的Guide Link是:https://jenkins.io/doc/p ...
- spring的@Transactional(rollbackFor=Exception.class)的使用
Spring框架的事务基础架构代码将默认地只在抛出运行时和unchecked exceptions时才标识事务回滚. 也就是说,当抛出个RuntimeException 或其子类例的实例时.(Erro ...
- redux 最简例子
方便初学redux的同学学习,这里是最简单的redux例子 1 import React, {Component, PropTypes} from 'react' 2 import ReactDOM ...
- oracle拆分一个连续的字符串
create or replace procedure pc( sss out varchar2)isstr varchar2(20):='ph,p,cod,do,cu';en integer:=i ...
- ubuntu14.04拼音输入法问题的解决方法
14.04的自带的拼音输入法,打字的时候你会发现有很大的问题,打不出来一个完整的字. 解决方法: ibus-daemon -drx //重启ibus进程 在终端里输一次这个命令就ok了. 或者装个 ...
- Pickle模块数据对象持久化操作
Pickle模块的作用是持久化(序列化)的储存数据.因此我先解释下:什么是序列化与反序列化.什么是对象序列化和对象反序列化.通俗地讲,它们的定义如下:序列化: 把一个对象保存到一个文件或数据库字段中去 ...
- 关于spring的IOC和DI的xml以及注解的简单介绍
xml 一 目的:通过ApplicationContext对象的getBean方法获取所需类的对象. 编写一个service类 public class service { private Strin ...