图像处理中去除杂点的方法有很多,低通,高通,高斯,均值,中值等等。 中值滤波的原理很简单,就是在图像中取3x1或3x3或其他的指定矩阵中的像素点的中间值。
本实验中,采用了一张1920x1280,24位的图片进行中值滤波,然后获RGB值和亮度。滤波矩阵为3x3,或5x5。并且对周围一圈不进行处理。 本机配置为I5 CPU + 8G内存。
一. 不采用并行处理,采用取值->用list.sort()进行排序->取中值。
for (int row = sideLength/2 ; row < height-sideLength/2; row++) //sideLength 取 3 或 5 { for (int column = sideLength / 2; column < width-sideLength / 2; column++) { Rectangle square = new Rectangle(column - sideLength / 2, row - sideLength / 2, sideLength, sideLength); int[] midValue = { 0, 0, 0 }; for (int channel = 0; channel < 3; channel++) { List<int> pixelValuesInSquare = new List<int>(); for (int rowOfSquare = square.Top; rowOfSquare < square.Bottom; rowOfSquare++) { for (int columnOfSquare = square.Left; columnOfSquare < square.Right; columnOfSquare++) { pixelValuesInSquare.Add(pixelValues[rowOfSquare * width + columnOfSquare, channel]); } } pixelValuesInSquare.Sort(); midValue[channel] = pixelValuesInSquare[pixelValuesInSquare.Count/ 2]; } double brightness = System.Drawing.Color.FromArgb(midValue[0], midValue[1], midValue[2]).GetBrightness(); if (brightness > this.MinimumBrightness) { reds.Add(midValue[0]); greens.Add(midValue[1]); blues.Add(midValue[2]); brightnesses.Add(brightness); } } }
测试一下时间:sideLength = 3 时: 平均时间 3139ms,其中排序 list.sort() 占用时间为 928ms。
二,考虑到插入排序算法中用linkedlist 进行时效率较高,所以修改了采用linkedlist进行插入排序。
for (int channel = 0; channel < 3; channel++) { LinkedList<int> pixelValuesInSquare = new LinkedList<int>(); for (int rowOfSquare = square.Top; rowOfSquare < square.Bottom; rowOfSquare++) { for (int columnOfSquare = square.Left; columnOfSquare < square.Right; columnOfSquare++) { int currentPixelValue = pixelValues[rowOfSquare * width + columnOfSquare, channel]; LinkedListNode<int> currentNode = pixelValuesInSquare.First; for (; currentNode != null; currentNode = currentNode.Next) { if (currentPixelValue < currentNode.Value) { LinkedListNode<int> newNode = pixelValuesInSquare.AddBefore(currentNode, currentPixelValue); break; } } if (null == currentNode) { LinkedListNode<int> newNode = pixelValuesInSquare.AddLast(currentPixelValue); } } } int squareSize = pixelValuesInSquare.Count; LinkedListNode<int> currNode = pixelValuesInSquare.First; for (int i = 0; i < squareSize / 2 ; i++, currNode = currNode.Next); midValue[channel] = currNode.Value;
测试时间: sideLength = 3 时, 平均时间为4383ms, 其中用for搜索中值的事件为:192ms. 可见并不比list.sort效率。
(注:当在list上面采用插入排序的时候,平均时间为6000ms以上)。
至此:效率为: list.sort()优于linkedlist,list上面采用插入排序的时候,效率最低。
三。在实验一中,采用平行算法。将事件缩短到2000ms。
后续:
后来发现,上述的思路是错误的,应该取亮度中值,然后统计其亮度的RGB值,可以用一个Struct来实现。
//var sortResult = brightnessesInSquare.OrderBy(pixel => pixel.brightness); brightnessesInSquare.Sort(); /* foreach (var item in sortResult) { if (indexOfSquare == (brightnessesInSquare.Count / 2)) { //Get mid value. midBrightnessInSquare = item; break; } indexOfSquare--; } * */
上述中,本来用Linq算法的时候,可以进行排序,后来将Stuct继承了IComparable接口后,用Sort就可以排序了 。 而且时间上面很短。