» Dynamic Plugin
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Dynamic Plugin

elliotwoods, Monday, Nov 14th 2011 Digg | Tweet | Delicious 2 comments  
elliotwoods 14/11/2011 - 04:28
#region using
using System.Collections.Generic;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
 
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VMath;
using System;
using VVVV.Utils.VColor;
 
#endregion
 
namespace VVVV.Nodes.EmguCV
{
    public class TemplateInstance : IFilterInstance
    {
        //example of a property
        private byte [] FColorAdd = new byte[3];
        public RGBAColor ColorAdd
        {
            //we don't expose the raw value, in case
            //we need to do some error checking
            //OpenCV loves throwing exceptions if its arguments aren't perfect :(
            //(in this instance we're not passing arguments to OpenCv)
            set
            {
                FColorAdd[0] = (byte)(value.R * 255.0);
                FColorAdd[1] = (byte)(value.G * 255.0);
                FColorAdd[2] = (byte)(value.B * 255.0);
            }
 
            //if changing these properties means we need to change the output image
            //size or colour type, then we need to call
            //Allocate();
        }
 
        protected override void InitialiseOutput()
        {
            //This function gets called whenever the output image needs to be initialised
            //Initialising = setting the attributes (i.e. setting the image header and allocating the memory)
            Size FHalfSize = FInput.ImageAttributes.Size;
            FHalfSize.Width /=2;
            FHalfSize.Height /=2;
 
            FOutput.Image.Initialise(FHalfSize, FInput.ImageAttributes.ColourFormat);
        }
 
        public override void Process()
        {
            //If we want to pull out an image in a specific format
            //then we must have a local instance of a CVImage initialised to that format
            //and use
            //FInput.Image.GetImage(TColourFormat.L8, FInputL8);
            //in that example, we expect to have a FInputL8 locally which has been intialised
            //with the correct size and colour format
 
 
            CvInvoke.cvPyrDown(FInput.CvMat, FOutput.CvMat, FILTER_TYPE.CV_GAUSSIAN_5x5);
 
            if (FInput.ImageAttributes.ColourFormat==TColourFormat.RGB8)
                PixelWiseAdd();
 
            FOutput.Send();
        }
 
        private unsafe void PixelWiseAdd()
        {
            //here's an example of accessing the pixels one by one
            //note the 'unsafe' in the function header
 
            //we've also presumed that the image is of the format RGB8 in order for
            //this example to work
            byte* rgb = (byte*)FOutput.Data.ToPointer();
            int width = FOutput.Image.Width;
            int height = FOutput.Image.Height;
 
            //for simplicity, i haven't clamped the colour values here
            for (int i = 0; i < width * height; ++i)
            {
                *rgb++ += FColorAdd[0];
                *rgb++ += FColorAdd[1];
                *rgb++ += FColorAdd[2];
            }
        }
    }
 
    #region PluginInfo
    [PluginInfo(Name = "Template", Category = "EmguCV", Version = "Filter", Help = "Template node for a threaded filter", Author = "", Credits = "", Tags = "")]
    #endregion PluginInfo
    public class TemplateNode : IFilterNode<TemplateInstance>
    {
        [Input("Add")]
        IDiffSpread<RGBAColor> FColorAdd;
 
        protected override void Update(int SpreadMax)
        {
            if (FColorAdd.IsChanged)
                for (int i = 0; i < SpreadMax; i++)
                    FProcessor[i].ColorAdd = FColorAdd[i];
        }
    }
}

You define 2 classes:

  1. The filter instance (inherits IFilterInstance)
  2. The node (inherits IFilterNode<your filter instance class>)

In the node, you use

protected override void Update(int SpreadMax)
{
    ..
}

rather than the usual Evaluate

The instance is managed by a ProcessInputOutputThreaded<T>

There's still likely to be some changes here but i'm trying to approach the point where the code within filters can be standardised

elliotwoods 14/11/2011 - 04:30

there's still a couple of bugs of course.
Note that if you change the spread count on the images, then FColorAdd inside the instance will just take the default value rather than the one from the pin

  • 1

anonymous user login

Shoutbox

~14d ago

~17d ago

joreg: The Winter Season of vvvv workshops is now over but all recordings are still available for purchase: https://thenodeinstitute.org/ws23-vvvv-intermediates/

~23d ago

schlonzo: Love the new drag and drop functionality for links in latest previews!

~1mth ago

joreg: Workshop on 29 02: Create Sequencers and Precise Clock Based Tools. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-08-create-sequencers-and-precise-clock-based-tools-in-vvvv-gamma/

~1mth ago

joreg: Workshop on 22 02: Unlocking Shader Artistry: A Journey through ‘The Book of Shaders’ with FUSE. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-12-book-of-shaders/

~2mth ago

joreg: Talk and Workshop on February 15 & 16 in Frankfurt: https://visualprogramming.net/blog/vvvv-at-node-code-frankfurt/

~2mth ago

woei: @Joanie_AntiVJ: think so, looks doable