| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- using System;
- using System.Linq;
- using System.Drawing;
- using System.Collections.Generic;
- namespace shjxCamera
- {
- /// <summary>
- /// 将队列中的前后两幅图像像素点进行相减,最大的10%和最小的10%视为噪点,其余值进行平均值计算
- /// </summary>
- public class NoiseDataFilter2
- {
- public NoiseDataFilter2()
- {
- Count = 2;
- lstImages = new List<List<Color>>();
- NoiseCnt = 10;
- }
- #region fields
- /// <summary>
- /// 队列中保留图像数,默认为2
- /// </summary>
- public int Count { get; set; }
- /// <summary>
- /// 过滤噪点数,单向
- /// </summary>
- public int NoiseCnt { get; set; }
- /// <summary>
- /// 用于比较的图像像素队列
- /// </summary>
- protected List<List<Color>> lstImages { get; set; }
- #endregion
- #region methods
- /// <summary>
- /// 加入一幅图像到队列,不做处理
- /// </summary>
- /// <param name="newImage"></param>
- public void AddImage(List<Color> newImage)
- {
- lstImages.Add(newImage);
- while (lstImages.Count > this.Count)
- {
- lstImages.RemoveAt(0);
- }
- }
- /// <summary>
- /// 对图像进行噪点过滤,然后计算rgb总值
- /// </summary>
- /// <param name="newImage"></param>
- /// <param name="sumR"></param>
- /// <param name="sumG"></param>
- /// <param name="sumB"></param>
- public void CalcImage(List<Color> newImage, ref int sumR, ref int sumG, ref int sumB)
- {
- AddImage(newImage);
- CalcAvg(ref sumR, ref sumG, ref sumB);
- }
- /// <summary>
- /// 清除队列数据
- /// </summary>
- public void Clear()
- {
- if (lstImages != null)
- {
- lstImages.Clear();
- }
- }
- #endregion
- #region protected methods
- /// <summary>
- /// 计算后图减前图的过滤图的总值
- /// </summary>
- /// <param name="sumR"></param>
- /// <param name="sumG"></param>
- /// <param name="sumB"></param>
- protected void calcAvg1(ref int sumR, ref int sumG, ref int sumB)
- {
- if (lstImages == null)
- {
- throw new Exception("队列没有数据");
- }
- if (lstImages.Count >= 2)
- {
- // 计算滤噪后的总值
- List<Color> img1 = lstImages[lstImages.Count - 2]; // 上一幅
- List<Color> img2 = lstImages[lstImages.Count - 1]; // 当前幅
- #region 计算后图减前图的差值
- string strr = "R:\r\n", strg = "G:\r\n", strb = "B:\r\n";
- List<IntRGB2> imgsub = new List<IntRGB2>();
- IntRGB2 val;
- for (int i = 0; i < img2.Count; i++)
- {
- val = new IntRGB2(
- img2[i].R - img1[i].R,
- img2[i].G - img1[i].G,
- img2[i].B - img1[i].B);
- imgsub.Add(val);
- /*if (this.IsLog)
- {
- strr = string.Format("{0}{1},", strr, val.R.ToString().PadLeft(3, ' '));
- strg = string.Format("{0}{1},", strg, val.G.ToString().PadLeft(3, ' '));
- strb = string.Format("{0}{1},", strb, val.B.ToString().PadLeft(3, ' '));
- if (i % this.LogWidth == 11)
- {
- strr = string.Format("{0}\r\n", strr);
- strg = string.Format("{0}\r\n", strg);
- strb = string.Format("{0}\r\n", strb);
- }
- }*/
- }
- /*if (this.IsLog)
- {
- //strr = string.Format("{0}\r\n", strr);
- //strg = string.Format("{0}\r\n", strg);
- //strb = string.Format("{0}\r\n", strb);
- swLog.WriteLine("相减数据:");
- swLog.WriteLine(strr);
- swLog.WriteLine(strg);
- swLog.WriteLine(strb);
- swLog.WriteLine();
- }*/
- #endregion
- #region 统计差值,以G值为准
- Dictionary<int, int> dicimg = new Dictionary<int, int>();
- foreach (IntRGB2 subval in imgsub)
- {
- if (dicimg.Keys.Contains(subval.G))
- {
- dicimg[subval.G] += 1;
- }
- else
- {
- dicimg.Add(subval.G, 1);
- }
- }
- List<KeyValuePair<int, int>> lstsub = dicimg.OrderByDescending(c => c.Key).ToList();
- #endregion
- #region 计算阈值参数
- NoiseParam2 npm = new NoiseParam2(NoiseCnt);
- npm.Threhold = img2.Count / 10;
- int tmp = 0; // 计算上阈值
- for (int i = 0; i < lstsub.Count; i++)
- {
- tmp += lstsub[i].Value;
- if (tmp < npm.Threhold)
- {
- //if (this.IsLog) { swLog.WriteLine("滤除噪点+:" + lstsub[i].Key.ToString() + "[" + lstsub[i].Value.ToString() + "点]"); }
- continue; // 未够数,继续下一组
- }
- else if (tmp == npm.Threhold)
- {
- // 正好够数,记录阈值,退出循环
- npm.Upper = lstsub[i].Key;
- npm.UpCnt = lstsub[i].Value; // 该阈值需消除的点数
- //if (this.IsLog) { swLog.WriteLine("滤除噪点+:" + lstsub[i].Key.ToString() + "[" + npm.UpCnt.ToString() + "点]"); }
- break;
- }
- else
- {
- // 过数,计算阈值,退出循环
- npm.Upper = lstsub[i].Key;
- npm.UpCnt = lstsub[i].Value - (tmp - npm.Threhold);
- //if (this.IsLog) { swLog.WriteLine("滤除噪点+:" + lstsub[i].Key.ToString() + "[" + npm.UpCnt.ToString() + "点]"); }
- break;
- }
- }
- tmp = 0; // 计算下阈值
- for (int i = lstsub.Count - 1; i >= 0; i--)
- {
- tmp += lstsub[i].Value;
- if (tmp < npm.Threhold)
- {
- //if (this.IsLog) { swLog.WriteLine("滤除噪点-:" + lstsub[i].Key.ToString() + "[" + lstsub[i].Value.ToString() + "点]"); }
- continue; // 未够数,继续下一组
- }
- else if (tmp == npm.Threhold)
- {
- // 正好够数,记录阈值,退出循环
- npm.Lower = lstsub[i].Key;
- npm.LowCnt = lstsub[i].Value; // 该阈值需消除的点数
- //if (this.IsLog) { swLog.WriteLine("滤除噪点-:" + lstsub[i].Key.ToString() + "[" + npm.LowCnt.ToString() + "点]"); }
- break;
- }
- else
- {
- // 过数,计算阈值,退出循环
- npm.Lower = lstsub[i].Key;
- npm.LowCnt = lstsub[i].Value - (tmp - npm.Threhold);
- //if (this.IsLog) { swLog.WriteLine("滤除噪点-:" + lstsub[i].Key.ToString() + "[" + npm.LowCnt.ToString() + "点]"); }
- break;
- }
- }
- #endregion
- #region 滤除噪点后,计算总值
- for (int i = 0; i < img2.Count; i++)
- {
- if (imgsub[i].G > npm.Upper || imgsub[i].G < npm.Lower)
- {
- continue; // 噪点,滤去
- }
- else if (imgsub[i].G == npm.Upper && npm.UpCnt > 0)
- {
- // 部分噪点,滤去部分
- npm.UpCnt--;
- continue;
- }
- else if (imgsub[i].G == npm.Lower && npm.LowCnt > 0)
- {
- // 部分噪点,滤去部分
- npm.LowCnt--;
- continue;
- }
- else
- {
- // 非噪点,计算总值
- sumR += img2[i].R;
- sumG += img2[i].G;
- sumB += img2[i].B;
- }
- }
- /*if (this.IsLog)
- {
- tmp = img2.Count - npm.Threhold * 2;
- strr = string.Format("总值:(R, G, B)({0}, {1}, {2}) 数据个数:{3}", sumR, sumG, sumB, tmp);
- swLog.WriteLine(strr);
- strr = string.Format("均值:(R, G, B)({0}, {1}, {2})\r\n", (sumR * 1.0 / tmp).ToString("F2"), (sumG * 1.0 / tmp).ToString("F2"), (sumB * 1.0 / tmp).ToString("F2"));
- swLog.WriteLine(strr);
- swLog.WriteLine();
- }*/
- #endregion
- }
- else
- {
- #region 仅一图,无法去噪,直接计算总值
- List<Color> img2 = lstImages[lstImages.Count - 1]; // 上一幅
- for (int i = 0; i < img2.Count; i++)
- {
- sumR += img2[i].R;
- sumG += img2[i].G;
- sumB += img2[i].B;
- }
- /*if (this.IsLog)
- {
- int tmp = img2.Count;
- string strr = string.Format("总值:(R, G, B)({0}, {1}, {2}) 数据个数:{3}", sumR, sumG, sumB, tmp);
- swLog.WriteLine(strr);
- strr = string.Format("均值:(R, G, B)({0}, {1}, {2})\r\n", (sumR * 1.0 / tmp).ToString("F2"), (sumG * 1.0 / tmp).ToString("F2"), (sumB * 1.0 / tmp).ToString("F2"));
- swLog.WriteLine(strr);
- swLog.WriteLine();
- }*/
- #endregion
- }
- }
- /// <summary>
- /// 计算后图减前图的过滤图的总值
- /// </summary>
- /// <param name="sumR"></param>
- /// <param name="sumG"></param>
- /// <param name="sumB"></param>
- protected void CalcAvg(ref int sumR, ref int sumG, ref int sumB)
- {
- if (lstImages == null)
- {
- throw new Exception("队列没有数据");
- }
- if (lstImages.Count >= 2)
- {
- // 计算滤噪后的总值
- List<Color> img1 = lstImages[lstImages.Count - 2]; // 上一幅
- List<Color> img2 = lstImages[lstImages.Count - 1]; // 当前幅
- #region 计算后图减前图的差值
- string strr = "R:\r\n", strg = "G:\r\n", strb = "B:\r\n";
- List<IntRGB2> imgsub = new List<IntRGB2>();
- IntRGB2 val;
- for (int i = 0; i < img2.Count; i++)
- {
- val = new IntRGB2(
- img2[i].R - img1[i].R,
- img2[i].G - img1[i].G,
- img2[i].B - img1[i].B);
- imgsub.Add(val);
- /*if (this.IsLog)
- {
- strr = string.Format("{0}{1},", strr, val.R.ToString().PadLeft(3, ' '));
- strg = string.Format("{0}{1},", strg, val.G.ToString().PadLeft(3, ' '));
- strb = string.Format("{0}{1},", strb, val.B.ToString().PadLeft(3, ' '));
- if (i % this.LogWidth == LogWidth - 1)
- {
- strr = string.Format("{0}\r\n", strr);
- strg = string.Format("{0}\r\n", strg);
- strb = string.Format("{0}\r\n", strb);
- }
- }*/
- }
- /*if (this.IsLog)
- {
- //strr = string.Format("{0}\r\n", strr);
- //strg = string.Format("{0}\r\n", strg);
- //strb = string.Format("{0}\r\n", strb);
- swLog.WriteLine("相减数据:");
- swLog.WriteLine(strr);
- swLog.WriteLine(strg);
- swLog.WriteLine(strb);
- swLog.WriteLine();
- }*/
- #endregion
- #region 统计差值,以G值为准
- Dictionary<int, int> dicimg = new Dictionary<int, int>();
- foreach (IntRGB2 subval in imgsub)
- {
- if (dicimg.Keys.Contains(subval.G))
- {
- dicimg[subval.G] += 1;
- }
- else
- {
- dicimg.Add(subval.G, 1);
- }
- }
- List<KeyValuePair<int, int>> lstsub = dicimg.OrderByDescending(c => c.Key).ToList();
- #endregion
- #region 计算阈值参数
- NoiseParam2 npm = new NoiseParam2(NoiseCnt);
- npm.Threhold = img2.Count / 10;
- int tmp = 0; // 计算上阈值
- for (int i = 0; i < lstsub.Count; i++)
- {
- tmp += lstsub[i].Value;
- if (tmp < npm.Threhold)
- {
- //if (this.IsLog) { swLog.WriteLine("滤除噪点+:" + lstsub[i].Key.ToString() + "[" + lstsub[i].Value.ToString() + "点]"); }
- continue; // 未够数,继续下一组
- }
- else if (tmp == npm.Threhold)
- {
- // 正好够数,记录阈值,退出循环
- npm.Upper = lstsub[i].Key;
- npm.UpCnt = lstsub[i].Value; // 该阈值需消除的点数
- //if (this.IsLog) { swLog.WriteLine("滤除噪点+:" + lstsub[i].Key.ToString() + "[" + npm.UpCnt.ToString() + "点]"); }
- break;
- }
- else
- {
- // 过数,计算阈值,退出循环
- npm.Upper = lstsub[i].Key;
- npm.UpCnt = lstsub[i].Value - (tmp - npm.Threhold);
- //if (this.IsLog) { swLog.WriteLine("滤除噪点+:" + lstsub[i].Key.ToString() + "[" + npm.UpCnt.ToString() + "点]"); }
- break;
- }
- }
- tmp = 0; // 计算下阈值
- for (int i = lstsub.Count - 1; i >= 0; i--)
- {
- tmp += lstsub[i].Value;
- if (tmp < npm.Threhold)
- {
- //if (this.IsLog) { swLog.WriteLine("滤除噪点-:" + lstsub[i].Key.ToString() + "[" + lstsub[i].Value.ToString() + "点]"); }
- continue; // 未够数,继续下一组
- }
- else if (tmp == npm.Threhold)
- {
- // 正好够数,记录阈值,退出循环
- npm.Lower = lstsub[i].Key;
- npm.LowCnt = lstsub[i].Value; // 该阈值需消除的点数
- //if (this.IsLog) { swLog.WriteLine("滤除噪点-:" + lstsub[i].Key.ToString() + "[" + npm.LowCnt.ToString() + "点]"); }
- break;
- }
- else
- {
- // 过数,计算阈值,退出循环
- npm.Lower = lstsub[i].Key;
- npm.LowCnt = lstsub[i].Value - (tmp - npm.Threhold);
- //if (this.IsLog) { swLog.WriteLine("滤除噪点-:" + lstsub[i].Key.ToString() + "[" + npm.LowCnt.ToString() + "点]"); }
- break;
- }
- }
- #endregion
- #region 滤除噪点后,计算总值
- double tmpR = 0.0, tmpG = 0.0, tmpB = 0.0;
- double tmpu = (dicimg[npm.Upper] - npm.UpCnt) * 1.0 / dicimg[npm.Upper]; // 部分过滤点保留的比率
- /*if (this.IsLog)
- {
- swLog.WriteLine(string.Format("噪点+:{0}[{1}/{2}]={3}", npm.Upper.ToString(), npm.UpCnt, dicimg[npm.Upper], tmpu.ToString("F2")));
- }*/
- double tmpd = (dicimg[npm.Lower] - npm.LowCnt) * 1.0 / dicimg[npm.Lower]; // 部分过滤点保留的比率
- /* if (this.IsLog)
- {
- swLog.WriteLine( string.Format("噪点-:{0}[{1}/{2}]={3}", npm.Lower.ToString(), npm.LowCnt, dicimg[npm.Lower], tmpd.ToString("F2")));
- }*/
- for (int i = 0; i < img2.Count; i++)
- {
- if (imgsub[i].G > npm.Upper || imgsub[i].G < npm.Lower)
- {
- continue; // 噪点,滤去
- }
- else if (imgsub[i].G == npm.Upper && npm.UpCnt > 0)
- {
- // 部分噪点,滤去部分
- tmpR += img2[i].R * tmpu;
- tmpG += img2[i].G * tmpu;
- tmpB += img2[i].B * tmpu;
- continue;
- }
- else if (imgsub[i].G == npm.Lower && npm.LowCnt > 0)
- {
- // 部分噪点,滤去部分
- tmpR += img2[i].R * tmpd;
- tmpG += img2[i].G * tmpd;
- tmpB += img2[i].B * tmpd;
- continue;
- }
- else
- {
- // 非噪点,计算总值
- tmpR += img2[i].R;
- tmpG += img2[i].G;
- tmpB += img2[i].B;
- }
- }
- sumR = Convert.ToInt32(tmpR);
- sumG = Convert.ToInt32(tmpG);
- sumB = Convert.ToInt32(tmpB);
- /*if (this.IsLog)
- {
- tmp = img2.Count - npm.Threhold * 2;
- strr = string.Format("处理总值:(R, G, B)({0}, {1}, {2}), 数据个数:{3}, ", sumR, sumG, sumB, tmp)
- + string.Format("均值:(R, G, B)({0}, {1}, {2})", (sumR * 1.0 / tmp).ToString("F2"), (sumG * 1.0 / tmp).ToString("F2"), (sumB * 1.0 / tmp).ToString("F2"));
- swLog.WriteLine(strr);
- //this.swLog.WriteLine();
- }*/
- #endregion
- }
- else
- {
- #region 仅一图,无法去噪,直接计算总值
- List<Color> img2 = lstImages[lstImages.Count - 1]; // 上一幅
- for (int i = 0; i < img2.Count; i++)
- {
- sumR += img2[i].R;
- sumG += img2[i].G;
- sumB += img2[i].B;
- }
- /* if (this.IsLog)
- {
- int tmp = img2.Count;
- string strr = string.Format("处理总值:(R, G, B)({0}, {1}, {2}), 数据个数:{3}, ", sumR, sumG, sumB, tmp)
- + string.Format("均值:(R, G, B)({0}, {1}, {2})", (sumR * 1.0 / tmp).ToString("F2"), (sumG * 1.0 / tmp).ToString("F2"), (sumB * 1.0 / tmp).ToString("F2"));
- swLog.WriteLine(strr);
- //this.swLog.WriteLine();
- }*/
- #endregion
- }
- }
- #endregion
- }
- /// <summary>
- /// 用int类型保存RGB三个值
- /// </summary>
- public class IntRGB2
- {
- #region properties
- public int R { get; set; }
- public int G { get; set; }
- public int B { get; set; }
- #endregion
- public IntRGB2()
- {
- R = 0;
- G = 0;
- B = 0;
- }
- public IntRGB2(int r, int g, int b)
- {
- R = r;
- G = g;
- B = b;
- }
- }
- /// <summary>
- /// 噪点相关参数
- /// </summary>
- public class NoiseParam2
- {
- /// <summary>
- /// 前后两图相减法,去除上下噪点
- /// </summary>
- /// <param name="threhold">上下各自噪点数</param>
- public NoiseParam2(int threhold)
- {
- Threhold = threhold;
- Upper = 0;
- UpCnt = 0;
- Lower = 0;
- LowCnt = 0;
- }
- #region
- /// <summary>
- /// 噪点个数
- /// </summary>
- public int Threhold { get; set; }
- /// <summary>
- /// 噪点上阈值
- /// </summary>
- public int Upper { get; set; }
- /// <summary>
- /// 上阈值噪点数个数
- /// </summary>
- public int UpCnt { get; set; }
- /// <summary>
- /// 噪点下阈值
- /// </summary>
- public int Lower { get; set; }
- /// <summary>
- /// 下阈值噪点个数
- /// </summary>
- public int LowCnt { get; set; }
- #endregion
- }
- }
|