Menu

Video Filtering / Color Filtering

2009-09-18
2012-10-29
  • Donald Leary

    Donald Leary - 2009-09-18

    Hello,
    could someone be so kind to give advice or point me in the right direction for
    the following circumstance:
    I am currently working on a directshow project that is taking input from a USB
    web cam and displaying the live video in its normal "default"
    colors. what i want to do is filter these colors to just 2 colors. example: i
    have a text document being displayed in my application, i would like to make
    the text Red and the background Black.
    my current method is taking each frame, determine the pixel brightness, if its
    over 60% transform that pixel red else black using Unsafe code in c#, i know
    there must be a better method,
    thank you in advance.
    don

     
  • snarfle

    snarfle - 2009-09-18

    It looks like most of the suggestions I would make for such a project you have
    already discovered:

    • Walk each pixel
    • Don't look for a hard coded value (ie 255, 255, 255), but use a threshold value.
    • Use Unsafe mode for decent performance

    Without having tried it to see the results, anything I can suggest would be a
    vague guess. However, if I were to approach this project, I'd be thinking
    along the lines of using 24 bit RGB colors. As I examine a pixel, if I decide
    it's going to be black, just paint it black. However, if I were thinking red,
    I would just set the G & B values to 0, and set the new R value to (255 -
    old R value). This would allow for some shading rather than everything being
    completely binary.

    But without being able to try it and experiment, it's hard for me to say
    whether this will result in clearer output than what you are already doing.

     
  • Donald Leary

    Donald Leary - 2009-09-18

    what is the formula for finding the threshold, here is the code for inverting
    the image, which is very fast:

    BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
    ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

    int stride = bmData.Stride;
    System.IntPtr Scan0 = bmData.Scan0;

    unsafe
    {
    byte p = ( byte)( void*)Scan0;

    int nOffset = stride - b.Width * 3;
    int nWidth = b.Width * 3;

    for (int y = 0; y < b.Height; ++y)
    {
    for (int x = 0; x < nWidth; ++x)
    {

    p = (byte)(255 - p);
    ++p;
    }
    p += nOffset;
    }
    }

    b.UnlockBits(bmData);

     
  • snarfle

    snarfle - 2009-09-18

    I don't think it is correct to say that there is a "formula" for
    finding the threshold.

    The problem is that there will be minor variations in how "white"
    the paper you are examining is. So, something that just looks white to you or
    me, the computer will see as slightly grey. And the bottom right corner of the
    page may be slightly different than top left. If you were going to do some
    all-up high quality professional grade app, I'd be thinking that you do an
    analysis of all the pixels on the page and calculate this for yourself. If
    that's your intent, good luck.

    Failing that, just pick some numbers for yourself. If 0,0,0 is black
    indicating the letters we want to show as red, and 255,255,255 is the white
    background you want to turn black, pick some method (maybe just adding the 3
    RGB values together) then pick some value (< 200) and give it a try. Change
    to suit, and maybe provide a way for the user to fiddle with it if they aren't
    getting the results they want.

    BTW, if performance is an issue, there are a variety of ways to improve what
    you have there. However, they will add complexity, so if you are getting the
    perf you want, perhaps you should leave it alone.

     
  • Donald Leary

    Donald Leary - 2009-09-21

    It really surprises me that DirectShow or AForge doesn't have this
    functionality on a lower level by accessing the video stream directly instead
    of my method of creating a bitmap from the stream, running that bitmap through
    the color filter algorithms and in most cases running it through interpolation
    methods for digital zoom. it just seems my attempt is more brute force than
    efficient. thank you for all your responses,, i think i may have to go lower
    than directX for video processing with some CCD or CMOS cams with low level
    SDK's.
    Don

     

Log in to post a comment.