opecv cartoon(外星人模式)

"cartoon.h"

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void cartoonifyImage(const Mat,Mat&);

///"cartoon.cpp"

#include<opencv2/opencv.hpp>
#include<iostream>
#include"cartoon.h"
int flag_CARTOONorMONSTER = 0;
void cartoonifyImage(const Mat srcImage,Mat &dstImage)
{
Mat mask;
Mat edges,edges2;
if(!flag_CARTOONorMONSTER){
Mat gray;
cvtColor(srcImage,gray,CV_BGR2GRAY);//转化成灰度值
const int MEDIAN_BLUR_FILTER_SIZE = 7;
medianBlur(gray,gray,MEDIAN_BLUR_FILTER_SIZE);//中值滤波
const int LAPLACIAN_FILTER_SIZE = 5;
Laplacian(gray,edges,CV_8U,LAPLACIAN_FILTER_SIZE);//拉普拉斯边缘滤波
const int EDGES_THRESHOLD = 80;
threshold(edges,mask,EDGES_THRESHOLD,255,THRESH_BINARY_INV);//类似于素描的样子了
}
/* if(flag_CARTOONorMONSTER){
Mat gray;
cvtColor(srcImage,gray,CV_BGR2GRAY);
const int MEDIAN_BLUR_FILTER_SIZE = 7;
medianBlur(gray,gray,MEDIAN_BLUR_FILTER_SIZE);

Scharr(gray,edges,CV_8U,1,0);
Scharr(gray,edges2,CV_8U,1,0,-1);
edges += edges2;
const int EVIL_EDGE_THRESHOLD = 12;
threshold(edges,mask,EVIL_EDGE_THRESHOLD,255,THRESH_BINARY_INV);
medianBlur(mask,mask,3);
}*/
Size size = srcImage.size();
Size smallSize;
smallSize.width = size.width/2;
smallSize.height = size.height/2;
Mat smallImg = Mat(smallSize,CV_8UC3);
resize(srcImage,smallImg,smallSize,0,0,INTER_LINEAR);//将图变小,低分辨率下使用双边滤波器
Mat temp = Mat(smallSize,CV_8UC3);
int repetitions = 7;
for(int i = 0;i<repetitions;i++){
int ksize = 9;
double sigmaColor = 9;
double sigmaSpace = 7;
bilateralFilter(smallImg,temp,ksize,sigmaColor,sigmaSpace);//双边滤波
bilateralFilter(temp,smallImg,ksize,sigmaColor,sigmaSpace);//多个小型滤波器代替大型滤波器,提高速度
}
Mat bigImg;
resize(smallImg,bigImg,size,0,0,INTER_LINEAR);
dstImage.setTo(0);
bigImg.copyTo(dstImage,mask);//卡通的样子
/**********开始画人脸轮廓**************/
Mat faceOutline = Mat::zeros(size,CV_8UC3);
Scalar color = CV_RGB(255,255,0);
int thickness = 4;
int Sw = size.width;
int Sh = size.height;
int faceH = Sw/2*70/100;
int faceW = faceH*72/100;
ellipse(faceOutline,Point(Sw/2,Sh/2),Size(faceW,faceH),0,0,360,color,thickness,CV_AA);
int eyeW = faceW*23/100;
int eyeH = faceH*11/100;
int eyeX = faceW*48/100;
int eyeY = faceH*13/100;
Size eyeSize = Size(eyeW,eyeH);
int eyeA = 15;
int eyeYshift = 11;
ellipse(faceOutline,Point(Sw/2-eyeX,Sh/2-eyeY),eyeSize,0,180+eyeA,360-eyeA,color,thickness,CV_AA);
ellipse(faceOutline,Point(Sw/2-eyeX,Sh/2-eyeY-eyeYshift),eyeSize,0,0+eyeA,180-eyeA,color,thickness,CV_AA);
ellipse(faceOutline,Point(Sw/2+eyeX,Sh/2-eyeY),eyeSize,0,180+eyeA,360-eyeA,color,thickness,CV_AA);
ellipse(faceOutline,Point(Sw/2+eyeX,Sh/2-eyeY-eyeYshift),eyeSize,0,0+eyeA,180-eyeA,color,thickness,CV_AA);
int mouthY = faceH*48/100;
int mouthW = faceW*45/100;
int mouthH = faceH*6/100;
ellipse(faceOutline,Point(Sw/2,Sh/2+mouthY),Size(mouthW,mouthH),0,0,180,color,thickness,CV_AA);

int fontFace = FONT_HERSHEY_COMPLEX;
float fontScale = 1.0f;
int fontThickness = 2;
char *szMsg = "Put your face here";
putText(faceOutline,szMsg,Point(Sw*23/100,Sh*10/100),fontFace,fontScale,color,fontThickness,CV_AA);
addWeighted(dstImage,1.0,faceOutline,0.7,0,dstImage,CV_8UC3);


/************将图变成Y'CrCb颜色空间************/
Mat yuv = Mat(smallSize,CV_8UC3);
cvtColor(smallImg,yuv,CV_BGR2YCrCb);
imshow("yuvImg",yuv);
int sw = smallSize.width;
int sh = smallSize.height;
Mat maskPlusBorder;
maskPlusBorder = Mat::zeros(sh+2,sw+2,CV_8UC1);
mask = maskPlusBorder(Rect(1,1,sw,sh));
resize(edges,mask,smallSize);
const int EDGES_THRESHOLD = 80;
threshold(mask,mask,EDGES_THRESHOLD,155,THRESH_BINARY);
dilate(mask,mask,Mat());
erode(mask,mask,Mat());
/*在鼻子前额选择6个点进行漫水填充***********/
int const NUM_SKIN_POINTS = 6;
Point skinPts[NUM_SKIN_POINTS];
skinPts[0] = Point(sw/2,      sh/2-sh/6);
skinPts[1] = Point(sw/2-sw/11,sh/2-sh/6);
skinPts[2] = Point(sw/2+sw/11,sh/2-sh/6);
skinPts[3] = Point(sw/2,      sh/2+sh/16);
skinPts[4] = Point(sw/2-sw/9, sh/2+sh/16);
skinPts[5] = Point(sw/2+sw/9, sh/2+sh/16);
const int LOWER_Y = 60;
const int UPPER_Y = 80;
const int LOWER_Cr = 25;
const int UPPER_Cr = 15;
const int LOWER_Cb = 20;
const int UPPER_Cb = 15;
Scalar lowerDiff = Scalar(LOWER_Y,LOWER_Cr,LOWER_Cb);
Scalar upperDiff = Scalar(UPPER_Y,UPPER_Cr,UPPER_Cb);

const int CONNECTED_COMPONETS = 4;
const int flags = CONNECTED_COMPONETS|FLOODFILL_FIXED_RANGE|FLOODFILL_MASK_ONLY;
Mat edgeMask = mask.clone();
for(int i = 0;i<NUM_SKIN_POINTS;i++){
floodFill(yuv,maskPlusBorder,skinPts[i],Scalar(),NULL,lowerDiff,upperDiff,flags);
}


Mat BGRImage;
cvtColor(yuv,BGRImage,CV_YCrCb2BGR);
mask -= edgeMask;
int Red = 0;
int Green = 70;
int Blue = 0;
Scalar color2 = CV_RGB(Red,Green,Blue);
add(BGRImage,color2,BGRImage,mask);
resize(BGRImage,BGRImage,size);
add(BGRImage,dstImage,dstImage);
}

"main.cpp"

#include<opencv2/opencv.hpp>
#include<iostream>
#include"cartoon.h"
using namespace std;
using namespace cv;
int main()
{
int cameraNumber = 0;
VideoCapture camera;
camera.open(cameraNumber);
if(!camera.isOpened()){
cout<<"ERROR!Could not access the camera or video!"<<endl;
exit(1);
}
camera.set(CV_CAP_PROP_FRAME_WIDTH,640);
camera.set(CV_CAP_PROP_FRAME_HEIGHT,480);
while(true){
Mat frame;
camera>>frame;
if(frame.empty()){
cout<<"ERROR!Could not grab a camera frame!"<<endl;
exit(0);
}
Mat displayFrame(frame.size(),CV_8UC3);
cartoonifyImage(frame,displayFrame);
imshow("Cartoonifier",displayFrame);
char keypress = waitKey(10);
if(keypress==27){
break;
}
}
}

### 回答1: 《Cartoon FX Remaster Bundle》是一个卡通特效包,用于增强动画或游戏中的卡通效果。这个包包含了各种各样的特效资源,供设计师使用,以创建更生动、更吸引人的卡通场景。 该特效包提供了丰富多样的功能,比如火焰、爆炸、烟雾、闪电、波浪等等,可以应用于不同的卡通场景中。这些特效资源设计精美,色彩鲜艳,具有鲜明的卡通风格,能够帮助设计师有效地表达出所需的情境和剧情。 此外,特效包还提供了可自定义参数的特效,使设计师能够根据自己的需求,进行特效的调整和修改。这种灵活性使得《Cartoon FX Remaster Bundle》成为一个非常实用的工具,适用于各种不同类型的卡通游戏和动画项目。 对于动画或游戏制作人员来说,《Cartoon FX Remaster Bundle》能够显著提高他们的工作效率和创作质量。这个特效包不仅仅是一个简单的资源库,更是一个强大的工具,可以帮助设计师轻松地实现他们的创意,并打造出令人惊叹的卡通场景。 总之,无论是专业的游戏开发者还是动画制作人员,都可以从《Cartoon FX Remaster Bundle》这个卡通特效包中获益。它提供丰富多样的特效资源,并允许自定义调整。使用它,可以轻松地创建出令人印象深刻的卡通特效,提高作品的可见度和吸引力。 ### 回答2: Cartoon FX Remaster Bundle是由一个团队设计和开发的一个动画特效包。这个特效包包含了许多激动人心和有趣的动画特效,可以用于游戏制作、动画制作以及其他多媒体项目。 这个特效包包括了各种各样的动画特效,例如爆炸、火焰、闪电、雨雪等等。这些特效都是经过精细的设计和优化的,可以帮助开发者和设计师以更高的质量和效率完成他们的项目。 这个特效包还提供了易于使用的工具和接口,可以让开发者和设计师轻松地使用这些特效。他们只需要导入特效包,然后根据自己的需求调整特效的参数,就可以快速地创建出华丽的动画特效。 Cartoon FX Remaster Bundle不仅可以节省制作时间,还可以增加动画效果的动感和趣味性。这些特效可以给游戏和动画带来更加生动和引人入胜的体验,吸引更多的观众和玩家。 总的来说,Cartoon FX Remaster Bundle是一个功能强大的动画特效包,它提供了丰富多样的特效和易于使用的工具,可以帮助开发者和设计师创造出令人惊叹和有趣的动画作品。无论是游戏制作还是动画制作,这个特效包都将是一个非常有价值的资源。 ### 回答3: "Cartoon FX Remaster Bundle"是一个卡通特效重制合集。它为创作者提供了一套全新的卡通特效工具,用于增强动画作品的视觉效果。这个合集包含了各种各样的卡通特效,如火焰、水流、烟雾、爆炸和闪电等,可以通过简单的拖放操作来应用到动画中。 这个合集的目的是提供一个方便易用的工具,让创作者能够轻松地为其动画作品添加独特的卡通效果。它不仅可以节省创作者的时间和精力,还能增强作品的视觉吸引力,使观众更容易与动画世界产生共鸣。 卡通特效在动画作品中起着非常重要的作用。它们可以增强故事情节的表达,让角色动作更生动,场景更真实。而这个合集的特效工具拥有高品质的视觉效果,可以根据创作者的需要进行个性化调整,以适应不同类型的动画风格。 "Cartoon FX Remaster Bundle"还附带了一些教程和示例文件,帮助创作者更好地使用特效工具,并为他们提供了一些灵感。它支持各种常见的动画软件,并且与不同操作系统兼容,可以在不同平台上使用。 总之,"Cartoon FX Remaster Bundle"是一个非常实用的卡通特效工具合集,可以帮助动画创作者轻松地为自己的作品添加独特的视觉效果,提升作品的质量和吸引力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值