» 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

~2d ago

joreg: vvvvTv S0204 is out: Custom Widgets with Dear ImGui: https://youtube.com/live/nrXfpn5V9h0

~2d ago

joreg: New user registration is currently disabled as we're moving to a new login provider: https://visualprogramming.net/blog/2024/reclaiming-vvvv.org/

~9d ago

joreg: vvvvTv S02E03 is out: Logging: https://youtube.com/live/OpUrJjTXBxM

~11d ago

~13d ago

joreg: Follow TobyK on his Advent of Code: https://www.twitch.tv/tobyklight

~16d ago

joreg: vvvvTv S02E02 is out: Saving & Loading UI State: https://www.youtube.com/live/GJQGVxA1pIQ

~16d ago

joreg: We now have a presence on LinkedIn: https://www.linkedin.com/company/vvvv-group

~24d ago

joreg: vvvvTv S02E01 is out: Buttons & Sliders with Dear ImGui: https://www.youtube.com/live/PuuTilbqd9w

~30d ago

joreg: vvvvTv S02E00 is out: Sensors & Servos with Arduino: https://visualprogramming.net/blog/2024/vvvvtv-is-back-with-season-2/

~30d ago