Bezdepbonusu7Программирование: статьи и ответы

Вопрос

C# Сканирование изображения для определенного блока

Автор вопроса: user779444Ответов: 3

У меня есть картина:

размер 1000x1000 белого цвета со случайными черными точками. (Может содержать черный квадрат (размер 50x50))

Есть ли простой способ узнать, содержит ли изображение черный квадрат (размер 50x50)? Я подумал о том, чтобы сканировать каждый пиксель картинки и, если нашелся черный пиксель, сканировать соседний с ним, пока не получится квадрат 50х50 или пока не получится белый пиксель и продолжать сканирование. но ему придется отсканировать более миллиона пикселей (если он не нашел квадрат).

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

        for (int i = 0; i < pic.Width; i++)
        {
            for (int j = 0; j < pic.Height; j++)
            {
                if (pic.GetPixel(i, j) == Color.Black)
                {
                    //Search for the entire square at that area
                }
            }
        }

И да, время важно (вот почему я не хочу получать пиксель более миллиона раз). Любые идеи?

imagepixel

Ответы

Ответ 1 · рейтинг 5 · Gabe

Подобно алгоритму поиска строк Бойера-Мура, если элемент, который вы ищете, at не является частью того, что вы ищете, вы можете пропустить весь размер того, что вы ищете. В вашем случае вы можете проверить, является ли данный пиксель черным. Если это не так, вы можете пропустить вперед 50 пикселей. Если это так, у вас есть небольшая коробка для поиска вашего черного квадрата.

Впрочем, в этом случае вам может и не понадобиться ничего столь сложного. Я предполагаю, что если ваш алгоритм слишком медленный, это потому, что вы вызываете функцию GetPixel миллион раз, и это медленная часть. Если вы сможете превратить свои пиксели в двумерный массив, ваш алгоритм, вероятно, будет работать достаточно быстро, чтобы его не нужно было переписывать.

Предполагая, что вы используете System.Drawing.Bitmap, ознакомьтесь с LockBits документацией. небольшой пример, который включает копирование растрового изображения в одномерный массив для сверхбыстрого доступа.

Ответ 2 · рейтинг 2 · Matthew Scharley

Если вы ищете только квадрат определенного размера, вы можете оптимизировать это, сканируя только каждую 50-ю строку (или столбец) пикселей, тем самым значительно сократив свою рабочую нагрузку.

Теоретически вам нужно проверять наличие черного/белого только в 1 пикселе из каждого блока 50x50. Если он черный, то вы пытаетесь распространить оттуда, если он белый, то просто переходите к следующему блоку: очевидно, что в этом блоке есть белый пиксель, поэтому здесь нет черного ящика. После этого вы уже сократили свою работу до 1/2500 от того, что было изначально, теперь вы сначала проверяете только 400 пикселей.

Обычно лучшая оптимизация, особенно при первоначальной разработке алгоритма, заключается в сокращении проделанной работы, а не в повышении ее эффективности. Попробуйте придумать творческие способы уменьшения ввода до более удобного размера.

Ответ 3 · рейтинг 1 · Pinakin Shah

ознакомьтесь с набором фреймворков AForge.net. Он имеет библиотеку изображений с поиском BLOB-объектов и шаблонов. Вы также можете искать формы. Это бесплатно.

Вы можете найти его здесь http://www.aforgenet.com/framework/

Вот ссылка, в которой перечислены функции

http://www.aforgenet.com/framework/features

Изменить

Вот образец для проверки формы. Я использовал Aforge в прототипе, и это сработало для меня.

http://www.aforgenet.com/articles/shape_checker/

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы