From 8bc47c7a4ec05f1d1e29de283a47923a1d6d340b Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 26 Aug 2013 13:18:02 +0100 Subject: finished json loader --- rotord/src/rotor.h | 171 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 152 insertions(+), 19 deletions(-) (limited to 'rotord/src/rotor.h') diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h index 2549683..da1ac8a 100755 --- a/rotord/src/rotor.h +++ b/rotord/src/rotor.h @@ -257,7 +257,7 @@ namespace Rotor { lut=nullptr; }; ~LUT(){if (lut) { delete[] lut;} }; - void generate(float black_in,float white_in,float black_out,float white_out,float gamma){ + void generate(float black_in,float white_in,float black_out,float white_out,float gamma){ //can check here if anything has changed if (lut) delete[] lut; lut=new unsigned char[256]; @@ -434,14 +434,14 @@ namespace Rotor { Image *output(const Frame_spec &frame){ if (palette.size()) { int col=((int)inputs[0]->get((Time_spec)frame))%palette.size(); - if (col!=prevcol){ //how about when starting a new render? + //if (col!=prevcol){ //how about when starting a new render? for (int i=0;iget(frame); if (in){ + int filtmode; + switch(attributes["filter"]->intVal){ + case TRANSFORM_nearest: + filtmode=cv::INTER_NEAREST; + break; + case TRANSFORM_linear: + filtmode=cv::INTER_LINEAR; + break; + case TRANSFORM_area: + filtmode=cv::INTER_AREA; + break; + case TRANSFORM_cubic: + filtmode=cv::INTER_CUBIC; + break; + case TRANSFORM_lanczos: + filtmode=cv::INTER_LANCZOS4; + break; + } + float tX=parameters["transformX"]->value; float tY=parameters["transformY"]->value; float oX=parameters["originX"]->value; @@ -732,7 +757,7 @@ namespace Rotor { dstTri[i].y=srcTri[i].y+(tY*in->h); } trans_mat=getAffineTransform( srcTri, dstTri ); - warpAffine( in->rgb, inter.rgb, trans_mat, inter.rgb.size(), cv::INTER_LINEAR, cv::BORDER_WRAP); + warpAffine( in->rgb, inter.rgb, trans_mat, inter.rgb.size(), filtmode, cv::BORDER_WRAP); // Compute rotation matrix @@ -742,7 +767,8 @@ namespace Rotor { rot_mat = getRotationMatrix2D( centre, r, s ); // Do the transformation // - warpAffine( inter.rgb, image.rgb, rot_mat, image.rgb.size(), cv::INTER_LINEAR, cv::BORDER_WRAP); + + warpAffine( inter.rgb, image.rgb, rot_mat, image.rgb.size(), filtmode, cv::BORDER_WRAP); //BORDER_WRAP //INTER_NEAREST - a nearest-neighbor interpolation @@ -793,49 +819,123 @@ namespace Rotor { Difference_matte(){ create_image_input("image input","Image input"); create_image_input("background input","Background input"); - create_parameter("threshold","number","Difference threshold","Threshold",0.05f,0.0f,1.0f); + create_parameter("threshold","number","Difference threshold","Threshold",0.2f,0.0f,1.0f); + create_parameter("feather","number","Feather width","Feather",0.1f,0.0f,1.0f); + create_parameter("weight_h","number","H component weight","Weight H",0.5f,0.0f,1.0f); + create_parameter("weight_s","number","S component weight","Weight S",0.5f,0.0f,1.0f); + create_parameter("weight_v","number","V component weight","Weight V",0.5f,0.0f,1.0f); + create_parameter("blursize","number","Blur size","Blur size",2.0f,0.0f,10.0f); create_attribute("mode","Output {image|alpha}","output mode","alpha",{"image","alpha"}); title="Difference matte"; description="Create an alpha channel using a background reference picture"; + LUT=nullptr; }; Difference_matte(map &settings):Difference_matte() { base_settings(settings); }; - ~Difference_matte(){}; + ~Difference_matte(){if (LUT) delete[] LUT;}; Difference_matte* clone(map &_settings) { return new Difference_matte(_settings);}; Image *output(const Frame_spec &frame){ Image *in1=image_inputs[0]->get(frame); if (in1){ Image *in2=image_inputs[1]->get(frame); if (in2) { - + generate_LUT(); + + /* cv::cvtColor(in1->rgb,greyfg,CV_RGB2GRAY); cv::cvtColor(in2->rgb,greybg,CV_RGB2GRAY); cv::absdiff(greyfg,greybg,greyDiff); //parameters["threshold"]->value cv::threshold(greyDiff,mask,parameters["threshold"]->value,255,CV_THRESH_BINARY); //int block_size=3, double param1=5); //int blockSize, int offset=0,bool invert=false, bool gauss=false); - + //cv::adaptiveThreshold(greyDiff,mask,255,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY, 3,5); //int block_size=3, double param1=5); //int blockSize, int offset=0,bool invert=false, bool gauss=false); + */ + + cv::cvtColor(in1->rgb, hsv1, CV_RGB2HSV); + cv::cvtColor(in2->rgb, hsv2, CV_RGB2HSV); + + mask.create(frame.h,frame.w,CV_8UC1); + lutmask.create(frame.h,frame.w,CV_8UC1); + + //get euclidean distance in HSV space + int dist,d; + uint8_t m; + + float weights[3] = {parameters["weight_h"]->value,parameters["weight_s"]->value,parameters["weight_v"]->value}; + float weight_total=255.0f/pow(pow(weights[0]*255,2)+pow(weights[1]*255,2)+pow(weights[2]*255,2),0.5); + + for (int i=0;ivalue/2.0)*2)+1,1.0); + //nb this doesn't do the intended: create 'continuously variable' blur + cv::GaussianBlur(mask,filtmask,cvSize(ksize,ksize),parameters["blursize"]->value); + + + for (int i=0;ivalue=="image"){ - image.setup_fromMat(mask); + cv::cvtColor(lutmask, image.rgb, CV_GRAY2RGB); } - else image.alpha_from_cv(mask); + else image.alpha_from_cv(lutmask); return ℑ - - //cv::cvtColor(in1->rgb, hsv1, CV_RGB2HSV); - //cv::cvtColor(in2->rgb, hsv2, CV_RGB2HSV); - + + + } //if there aren't 2 image inputs connected just return the first return in1; } return nullptr; } + void generate_LUT(){ + //can check here if anything has changed + //cerr<<"generating LUT: threshold "<value<<", feather "<value<value-(parameters["feather"]->value*0.5f)); + float maxf=min(1.0f,parameters["threshold"]->value+(parameters["feather"]->value*0.5f)); + for (int i=0;i<256;i++){ + LUT[i]=(uint8_t)(min(1.0f,max(0.0f,((((float)i)/255.0f)-minf)/(maxf-minf)))*255.0f); + // cerr<<((int)LUT[i])<<" "; + } + //cerr<get(frame); + Image *in=image_inputs[0]->get(frame); + if (in){ + //make copy of the image, for feedback + //optimise? + image=(*in); + return ℑ + } + return nullptr; }; Video_output* clone(map &_settings) { return new Video_output(_settings);}; bool render(const float duration, const float framerate,const string &output_filename,const string &audio_filename,float& progress,int w,int h); private: + }; + class Video_feedback: public Image_node { + public: + Video_feedback(){ + title="Video feedback"; + description="Repeats output of the last frame"; + feedback=nullptr; + }; + Video_feedback(map &settings):Video_feedback() { + base_settings(settings); + }; + ~Video_feedback(){ }; + void set_feedback(Image *iptr){ + feedback=iptr; + } + Image *output(const Frame_spec &frame){ + if (feedback->RGBdata){ + return feedback; + } + image.setup(frame.w,frame.h); + image.clear(); + return ℑ + }; + Video_feedback* clone(map &_settings) { return new Video_feedback(_settings);}; + private: + Image *feedback; }; //------------------------------------------------------------------- class Node_factory{ @@ -983,7 +1116,7 @@ namespace Rotor { if (type.second->description!="") { //blank description = internal/ testing node list_node(type,XML,i); i++; - } + } } } void list_nodes(Json::Value &JSON){ @@ -1051,7 +1184,7 @@ namespace Rotor { } } JSON["nodeslist"].append(node); - } + } } } private: -- cgit v1.2.3