2016-03-04 23:36
3414人阅读
收藏
举报
为什么美颜摄像这么简单的功能,OpenCV这个开源项目网上很少有代码呢?对于在windows平台下,生成h264视频流也比价麻烦,没有现成的api可以使用,需要借助MinGw编译libx264,或者ffmpeg才能使用。
最近有个小需求,要推送直播视频流,我在网上查了一下有live555或者用librtmp来推送,但是前者还需要修改源代码,也挺麻烦的,现在先做到了下面几个步骤:
1.OpenCV捕捉摄像头的图像
2.进行识别需要美颜的部分(人脸识别,肤色识别)
3.进行美颜(提升亮度,直方图均衡,滤波)
4.生成YUV视频
5.生成h264
现在用librtmp时候,出现了
ERROR:RTMP_Connect0,failed to connect socket,10061(unknow error)
不知道是咋回事了,怀疑是1935端口被禁,但是一时半会儿不知道咋弄。
主要功能代码:
-
-
- string face_cascade_name = "haarcascade_frontalface_alt.xml";
-
- CascadeClassifier face_cascade;
- CascadeClassifier eyes_cascade;
- string window_name_onlyface = "Capture - only Face";
- string window_name_face = "Capture - Face ";
-
-
-
-
-
- void detectAndenhance( Mat &frame )
- {
- std::vector faces;
- Mat frame_gray;
- Mat hatAlpha;
-
-
-
- cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
-
-
- face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
-
- for( size_t i = 0; i < faces.size(); i++ )
- {
- Rect face(faces[i].x,faces[i].y,faces[i].x + faces[i].width,faces[i].y + faces[i].height);
- cvSetImageROI(&IplImage(frame),face);
-
-
-
-
- blur(frame,frame,Size(7,7),Point(-1,-1));
-
- cvResetImageROI( &IplImage(frame) );
- Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
- ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar( 255, 0, 255 ), 2, 8, 0 );
-
-
-
- Mat faceROI = frame_gray( faces[i] );
- std::vector eyes;
-
- imshow( window_name_onlyface, faceROI );
-
- }
-
- imshow( window_name_face, frame );
-
- }
-
-
- void detectAndDisplay( Mat frame )
- {
- std::vector faces;
- Mat frame_gray;
-
- cvtColor( frame, frame_gray, CV_BGR2GRAY );
- equalizeHist( frame_gray, frame_gray );
-
-
- face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
-
- for( int i = 0; i < faces.size(); i++ )
- {
- Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
- ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
-
- Mat faceROI = frame_gray( faces[i] );
- std::vector eyes;
-
-
- eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
-
- for( int j = 0; j < eyes.size(); j++ )
- {
- Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
- int radius = cvRound( (eyes[j].width + eyes[i].height)*0.25 );
- circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
- }
- }
-
- imshow( window_name_face, frame );
- }
-
-
-
-
-
- Mat equalizeChannelHist(const Mat & inputImage)
- {
- if( inputImage.channels() >= 3 )
- {
- vector channels;
- split(inputImage, channels);
-
- Mat B,G,R;
-
- equalizeHist( channels[0], B );
- equalizeHist( channels[1], G );
- equalizeHist( channels[2], R );
-
- vector combined;
- combined.push_back(B);
- combined.push_back(G);
- combined.push_back(R);
-
- Mat result;
- merge(combined, result);
-
- return result;
- }
- else{return inputImage;}
-
- return inputImage;
- }
-
-
- Mat equalizeIntensityHist(const Mat & inputImage)
- {
- if(inputImage.channels() >= 3)
- {
- Mat ycrcb;
-
- cvtColor(inputImage, ycrcb, COLOR_BGR2YCrCb);
-
- vector channels;
- split(ycrcb, channels);
-
- equalizeHist(channels[0], channels[0]);
-
- Mat result;
- merge(channels,ycrcb);
-
- cvtColor(ycrcb, result, COLOR_YCrCb2BGR);
-
- return result;
- }
-
- return Mat();
- }
-
-
-
-
- void MySkinEnhance(Mat &frame)
- {
- Mat input_image =frame;
- Mat output_mask;
- Mat output_image;
- Mat mask;
-
-
- Mat skinCrCbHist = Mat::zeros(Size(256, 256), CV_8UC1);
- ellipse(skinCrCbHist, Point(113, 155.6), Size(23.4, 15.2), 43.0, 0.0, 360.0, Scalar(255, 255, 255), -1);
-
- Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1) );
-
- if(input_image.empty())
- return ;
-
- Mat ycrcb_image;
- output_mask = Mat::zeros(input_image.size(), CV_8UC1);
- cvtColor(input_image, ycrcb_image, CV_BGR2YCrCb);
-
- for(int i = 0; i < input_image.rows; i++)
- {
- uchar* p = (uchar*)output_mask.ptr(i);
- Vec3b* ycrcb = (Vec3b*)ycrcb_image.ptr(i);
- for(int j = 0; j < input_image.cols; j++)
- {
- if(skinCrCbHist.at(ycrcb[j][1], ycrcb[j][2]) > 0)
- p[j] = 255;
- }
- }
-
-
-
-
-
- dilate(output_mask,output_mask,Mat(32,32,CV_8U),Point(-1,-1),2);
-
-
- input_image.copyTo(output_image, output_mask);
-
- Mat enhance = output_image;
- medianBlur(output_image,enhance,11);
-
- imshow("blur face",enhance);
- for(int i = 0; i < output_image.rows; i++)
- {
- uchar* p = (uchar*)output_mask.ptr(i);
-
- for(int j = 0; j < output_image.cols; j++)
- {
- if((enhance.at(i,j)[0] < 50) && (enhance.at(i,j)[1] < 50)&& (enhance.at(i,j)[2] < 50) )
- {
-
-
-
- }
- else
- {
-
- frame.at(i,j)[0] = enhance.at(i,j)[0];
-
- frame.at(i,j)[1] = enhance.at(i,j)[1];
- frame.at(i,j)[2] = enhance.at(i,j)[2];
- }
- }
- }
-
-
- imshow("ouput image",frame);
-
- }
-
-
-
- void highlight(Mat &frame)
- {
- Mat src,dst;
- double alpha =1.5;
- double beta = 20;
-
- src = frame;
- if(!src.data)
- {
- cout<<"Failed to load image!"<
- return ;
- }
-
-
-
-
- for (int i = 0;i
- {
-
-
- for(int j= 0;j
- {
-
-
-
-
-
- src.at(i,j)[0] = (src.at(i,j)[0]*alpha+beta);
- src.at(i,j)[1] = (src.at(i,j)[1]*alpha+beta);
- src.at(i,j)[2] = (src.at(i,j)[2]*alpha+beta);
-
- }
- }
-
- namedWindow("Handled Image");
- imshow("Handled Image",src);
-
- }
实现效果:实时实现的话我只加了肤色检测和简单的滤波,具体美化还需要进一步调试
参数和算法 的组合可以在代码中调整参数实现,可以把膨胀的参数调大一点这个整个人脸就差不多可以经过肤色检测全部搞出来。
完整工程代码:http://download.csdn.net/detail/wangyaninglm/9453146

参考文献:
肤色检测:http://blog.csdn.net/yangtrees/article/details/8269984
人像优化:http://blog.csdn.net/u011630458/article/details/46275469
肤色检测:http://blog.csdn.net/wj080211140/article/details/23384927
改变对比读:http://blog.csdn.net/ubunfans/article/details/24373811
直接推送直播流:http://blog.csdn.net/wangyaninglm/article/details/51056101