Методы обработки изображений - прямое манипулирование целевым изображением или виртуализация?

Мне нужно повторно спроецировать серию изображений Ариэля, которые были привязаны в географической системе координат, в проекцию UTM. Я читал, что использование getPixel и setPixel может быть медленным - следует установить серию 2-мерных массивов для промежуточного доступа, а затем сбросить значения в целевое изображение, когда я закончу.

Обычно это обработка изображений выполняется профессионалами?

4 ответа

Решение

Большая часть обработки изображений - это обнаружение признаков, сегментация сцены, поиск неисправностей, классификация и отслеживание....

Вы можете взглянуть на книгу:

  1. Обработка изображений на С (применима и для других языков)
  2. Обработка изображений - принципы и применение

Который описывает множество быстрых и эффективных способов многих преобразований изображений. Эти две книги помогли мне, когда я обрабатывал изображения:)

Если я понимаю ваш вопрос... Если вы повторно выравниваете или собираете много изображений, и у вас нет ориентации, а также положения, вы можете использовать эти алгоритмы для повторного выравнивания краев и общих характеристик. Если вы выполняете сшивание по положению, тогда эти алгоритмы помогут повторно сэмплировать / изменить размеры ваших изображений для более эффективной сборки. Есть также несколько библиотек с открытым исходным кодом для такого рода вещей. (На ум приходит OpenCV)

редактировать: если бы я повторно проецировал большие изображения в новые проекции, основанные на преобразовании положения (и это было динамическое, а не статическое), я бы посмотрел на создание приложения по требованию, которое будет рефакторировать изображения с требуемым разрешением и желаемой позицией. Затем приложение может получить самое близкое разрешение изображений относительного соседства и предоставить результат с желаемым разрешением.

Надеюсь, без дополнительной информации это поможет!

edit 2: Комментарий от ответа ниже: Зависит от изображений. Если они имеют фиксированный размер, то массив может быть хорошим. Если они различаются, то может быть лучше внедрить систему, которая обеспечивает get / setpixel, используя относительную выборку / усреднение для сопоставления изображений с разным разрешением?

Я не знаю все входы и выходы изображений, с которыми вы работаете, и того, что вы делаете, но часто полезно абстрагироваться от "пикселя", а не от доступа к значениям в массиве. Таким образом, вы можете реализовать алгоритмы преобразования, выборки, поворота, исправления на бэкэнде. Как GetVPixel() или SetVPixel(). Это может быть более полезно при работе с несколькими, разными изображениями в формате res/format. подобно

SetVPixel(img1, coord1, GetVPixel(img2, coord2))

Очевидно, в ООП /C# манере. img1 и img2 могут отличаться по размеру, размеру, географическому расположению, выравниванию или чему-либо еще, если ваш бэкэнд понимает и то, и другое.

Если вы не возражаете против использования небезопасного кода, вы можете поместить BitmapData в растровое изображение в объект, который позволяет эффективно получать и устанавливать пиксели. Приведенный ниже код в основном взят из фильтра размытия по Гауссу, с несколькими моими модификациями. Это не самый гибкий код, если ваши форматы растровых изображений отличаются, но я надеюсь, что он иллюстрирует, как вы можете более эффективно управлять растровыми изображениями.

public unsafe class RawBitmap : IDisposable
{
    private BitmapData _bitmapData;
    private byte* _begin;

    public RawBitmap(Bitmap originBitmap)
    {
        OriginBitmap = originBitmap;
        _bitmapData = OriginBitmap.LockBits(new Rectangle(0, 0, OriginBitmap.Width, OriginBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        _begin = (byte*)(void*)_bitmapData.Scan0;
    }

    #region IDisposable Members

    public void Dispose()
    {
        OriginBitmap.UnlockBits(_bitmapData);
    }

    #endregion

    public unsafe byte* Begin
    {
        get { return _begin; }
    }

    public unsafe byte* this[int x, int y]
    {
        get
        {
            return _begin + y * (_bitmapData.Stride) + x * 3;
        }
    }

    public unsafe byte* this[int x, int y, int offset]
    {
        get
        {
            return _begin + y * (_bitmapData.Stride) + x * 3 + offset;
        }
    }

    public unsafe void SetColor(int x, int y, Color color)
    {
        byte* p = this[x, y];
        p[0] = color.B;
        p[1] = color.G;
        p[2] = color.R;
    }

    public unsafe Color GetColor(int x, int y)
    {
        byte* p = this[x, y];

        return new Color
        (
            p[2],
            p[1],
            p[0]
        );
    }

    public int Stride
    {
        get { return _bitmapData.Stride; }
    }

    public int Width
    {
        get { return _bitmapData.Width; }
    }

    public int Height
    {
        get { return _bitmapData.Height; }
    }

    public int GetOffset()
    {
        return _bitmapData.Stride - _bitmapData.Width * 3;
    }

    public Bitmap OriginBitmap { get; private set; }
}

Библиотека FreeImage довольно быстрая и предлагает вырезать и вставить, которые могут быть полезны. Дистрибутив поставляется с оболочкой C#.

AFAIK издержки GetPixel/SetPixel - это вызов к нему, при обращении к массиву нет вызова, следовательно, меньше накладных расходов.

Вы должны начать с GetPixel/SetPixel, вы всегда можете переопределить эти вызовы позже, чтобы использовать прямой доступ к данным.

Другие вопросы по тегам