中值滤波和效率

图像处理中去除杂点的方法有很多,低通,高通,高斯,均值,中值等等。 中值滤波的原理很简单,就是在图像中取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就可以排序了 。 而且时间上面很短。 

原文地址:https://www.cnblogs.com/fdyang/p/2941748.html