Linq вместо двух петель получает цвет пикселя и указывает на изображение - PullRequest
0 голосов
/ 13 октября 2011

Как я могу использовать linq для вывода списка всех пикселей из изображения и обработки на них? Например, у нас есть:

 for (int i = 0; i < this.bitmap.Width; i++)
            {
                for (int j = 0; j < this.bitmap.Height; j++)
                {
                    bitmap.SetPixel(x, y, Color.FromArgb(1, 1, 1));
                }
            }

Здесь мне не нужны пиксели списка, потому что я работаю немедленно, используя пока что для циклов. Однако я не уверен, смогу ли я обработать изображение с помощью linq. Я понимаю, что linq получает данные, поэтому я хотел бы взять пиксель из точки и каким-то образом сохранить координаты и данные цвета этого пикселя. Мне это нужно, потому что как я смогу сделать порог?

Я пытался использовать struct, но на странице http://social.msdn.microsoft.com/Forums/is/linqtosql/thread/02154de8-ef32-4420-a3f6-e4e473df66ce они сказали, что linq не работает со struct.

Может быть, я должен использовать список, но когда я написал List<Point, Color> list Я получил ошибку. Так что я действительно не знаю, как это сделать ..

Все собирается оптимизировать мою функцию в соответствии с этим текстом. Я прочитал в книге под названием «Программирование Effectice в C #», что использование синтаксиса запроса будет более читабельным, чем для циклов ..

Это мой код, и я действительно прошу вас помочь, как сделать его более читабельным.

пс. пожалуйста, исправьте тему, если она мне не подходит, извините.

private void ThreshGrayTails () {

        this.tempBitmap = new Bitmap(this.bitmap);

        for (int i = 0; i < this.bitmap.Width; i++)
        {
            for (int j = 0; j < this.bitmap.Height; j++)
            {
                SetTempPixelInt(i, 0, j, 0, this.tempBitmap);

                if (this.tempPixelInt == 252 && (j + 2) < this.bitmap.Height && (j - 2) > 0)
                {
                    SetTempPixelInt(i, 0, j, -1, this.bitmap);

                    //if pixel above has value 252
                    if (this.tempPixelInt == 252)
                    {
                        SetTempPixelInt(i, 0, j, -2, this.bitmap);

                        //if pixel above has value 159
                        if (this.tempPixelInt == 159)
                        {
                            SetTempPixelInt(i, 0, j, +1, this.bitmap);

                            //if pixel under has value 0 or 172
                            if (this.tempPixelInt == 0 || this.tempPixelInt == 172)
                            {
                                this.tempBitmap.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                                this.tempBitmap.SetPixel(i - 1, j, Color.FromArgb(255, 255, 255));
                                this.tempBitmap.SetPixel(i - 2, j, Color.FromArgb(255, 255, 255));
                            }
                        }
                    }

                }

                //if current pixel doesnt contain value in that list, turn it on black
                if (!colorsToThreshold.Contains(this.tempBitmap.GetPixel(i, j).R))
                {
                    Color newcolor = Color.FromArgb(0, 0, 0);
                    this.tempBitmap.SetPixel(i, j, newcolor);
                }
                //if current pixel contain value in that list, turn it on white
                else
                {
                    Color newcolor = Color.FromArgb(255, 255, 255);
                    this.tempBitmap.SetPixel(i, j, newcolor);
                }

            }

        }
        this.bitmap = new Bitmap(this.tempBitmap);
        SaveImage("thresholded.bmp", this.bitmap);
    }

    private void SetTempPixelInt(int i, int pi, int j, int pj, Bitmap bitmap)
    {
        Color currentColor = bitmap.GetPixel(i + pi, j + pj);
        this.tempPixelInt = (int)(currentColor.R);
    }

Ответы [ 2 ]

1 голос
/ 13 октября 2011

Все, что собирается оптимизировать мою функцию в соответствии с этим текстом

Если вы хотите повысить производительность, лучшим решением для вас будет использование небезопасного кода для доступа к пикселям непосредственно в памяти. Вы должны использовать метод LockBits () в Bitmap для достижения этой цели. Некоторые примеры быстрой обработки изображений в c # можно найти здесь: http://www.vcskicks.com/fast-image-processing.php

LINQ действительно не является решением такой проблемы.

1 голос
/ 13 октября 2011

Я думаю, что вы пытаетесь исправить неправильный код.

Пиксели на изображении недоступны как коллекция, поэтому вы не можете использовать LINQ для них изкоробка.Вам нужно создать что-то, что может дать вам пиксели в виде коллекции, чтобы использовать их в запросе.Вы можете использовать метод Range для создания запроса, в котором вы можете получить доступ к пикселям, но это будет медленным и сложным способом выполнения того, что вы уже делаете в своих циклах.

Статья, в которой выпрочитайте, что LINQ не работает со структурами, применяется к LINQ to SQL, который вы не используете.Однако использование структуры на самом деле не облегчит использование LINQ для этого.

...