OpenCV c#版 CodeBook

来源:互联网 发布:mysql二进制安装 编辑:程序博客网 时间:2024/05/09 07:03
using OpenCvSharp;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 指向手势识别{    public class CodeBook    {        #region cede_Element        private static int CHANNELS = 3;        private class CodeElement        {            public int[] learnHigh = new int[CHANNELS];            public int[] learnLow = new int[CHANNELS];            public int[] max = new int[CHANNELS];            public int[] min = new int[CHANNELS];            public int tLastUpdate = 0;            public int stale = 0;            public CodeElement()            {            }            public CodeElement(CodeElement element)            {                this.Copy(element);            }            public void Copy(CodeElement element)            {                for (int i = 0; i < CHANNELS; i++)                {                    learnHigh[i] = element.learnHigh[i];                    learnLow[i] = element.learnLow[i];                    max[i] = element.max[i];                    min[i] = element.min[i];                }                tLastUpdate = element.tLastUpdate;                stale = element.stale;            }        }        #endregion        #region 私有字段        /// <summary>        /// 码元记录表        /// </summary>        private List<CodeElement> cb;        /// <summary>        /// 码元总数目        /// </summary>        private int numEntries;        /// <summary>        /// 当前时间        /// </summary>        private static int t;        public int NumEntries        {            get { return numEntries; }            set { numEntries = value; }        }        public static int T        {            get { return t; }            set { t = value; }        }        #endregion        public CodeBook()        {            CodeBook.t = 0;            this.NumEntries = 0;            this.cb = new List<CodeElement>();        }        public void Initial()        {            this.cb.Clear();            this.NumEntries = 0;            CodeBook.t = 0;        }        public int UpdateCodeBook(int[] pixel, int[] cbBound, int numChannels)        {            if (this.NumEntries == 0)                CodeBook.t = 0;            CodeBook.t++;            #region 记录新像素点高低范围            int[] high = new int[3];            int[] low = new int[3];            for (int i = 0; i < numChannels; i++)            {                high[i] = pixel[i] + cbBound[i];                if (high[i] > 255)                    high[i] = 255;                low[i] = pixel[i] - cbBound[i];                if (low[i] < 0)                    low[i] = 0;            }            #endregion            #region 寻找匹配码元并更新数值            int matchChannel, index;            for (index = 0; index < this.NumEntries; index++)            {                matchChannel = 0;                for (int i = 0; i < numChannels; i++)                {                    if (this.cb[index].learnLow[i] <= pixel[i] &&                        pixel[i] <= this.cb[index].learnHigh[i])                    {                        matchChannel++;                    }                }                //找到匹配的码元,更新最大值最小值区域                if (matchChannel == numChannels)                {                    CodeElement element = this.cb[index];                    element.tLastUpdate = CodeBook.t;                    for (int i = 0; i < numChannels; i++)                    {                        if (element.max[i] < pixel[i])                        {                            element.max[i] = pixel[i];                        }                        else if (element.min[i] > pixel[i])                        {                            element.min[i] = pixel[i];                        }                    }                    break;                }            }            #endregion            #region 更新每个码元点的最后修改时间            for (int i = 0; i < this.NumEntries; i++)            {                int negRun = CodeBook.t - this.cb[i].tLastUpdate;                if (this.cb[i].stale < negRun)                {                    CodeElement element = this.cb[i];                    element.stale = negRun;                }            }            #endregion            #region 没有找到当前匹配的码元,添加一个新的码元            if (index == this.NumEntries)            {                CodeElement element = new CodeElement();                for (int i = 0; i < numChannels; i++)                {                    element.learnHigh[i] = high[i];                    element.learnLow[i] = low[i];                    element.max[i] = pixel[i];                    element.min[i] = pixel[i];                }                element.tLastUpdate = CodeBook.t;                element.stale = 0;                this.cb.Add(element);                this.NumEntries++;            }            #endregion            #region 如果发现像素在box阈值之外,但仍然在其高低范围内,缓慢调整learnHigh和learnLow的学习界限            for (int i = 0; i < numChannels; i++)            {                CodeElement element = this.cb[index];                if (element.learnHigh[i] < high[i])                {                    element.learnHigh[i]++;                }                if (element.learnLow[i] > low[i])                {                    element.learnLow[i]--;                }            }            #endregion            return index;        }        public int ClearStaleEntries()        {            int staleThresh = CodeBook.t >> 1;            for (int i = 0; i < this.cb.Count; i++)            {                if (this.cb[i].stale > staleThresh)                {                    this.cb.RemoveAt(i);                }            }            int result = this.NumEntries;            this.NumEntries = this.cb.Count;            result -= this.NumEntries;            return result;        }        public bool BackGroundDiff(int[] pixel, int[] minMod, int[] maxMod, int numChannels)        {            bool result = true;            foreach (CodeElement element in this.cb)            {                int matchChannel = 0;                for (int i = 0; i < numChannels; i++)                {                    if (element.min[i] - minMod[i] <= pixel[i] &&                        pixel[i] <= element.max[i] + maxMod[i])                    {                        matchChannel++;                    }                    else                    {                        break;                    }                }                if (matchChannel == numChannels)                {                    //不是前景目标                    result = false;                    break;                }            }            return result;        }    }}

0 0
原创粉丝点击