Избавление от тонкой границы по краю с прозрачностью при сглаживании с помощью библиотеки изображений Python

У меня есть изображение с высоким разрешением, которое я хочу использовать в качестве мозаичного наложения карты с помощью Google Maps API v3.

Я использовал MapTiler, чтобы разбить его на соответствующие плитки с желаемым уровнем масштабирования. Это работало хорошо, за исключением того, что на плитках, которые были краями исходного изображения, была тонкая серо-черная рамка.

Следуя предложению во втором сообщении на http://groups.google.com/group/maptiler/browse_thread/thread/70a4c5610538332a/42fefedb4a0bc6d2 вместо этого я попытался использовать gdal2tiles.py, передав ему параметр -r antialias, но тонкая рамка осталась.

Если я открою фактически сгенерированные фрагменты изображения, тонкая рамка действительно окажется частью сгенерированного фрагмента, но не частью исходного изображения.

Я подозреваю, что происходит то, что части плитки Google Maps, для которых у меня нет данных, обрабатываются как черные пиксели, когда программа генерирует файлы изображений плитки, и результатом является серая рамка.

Вот что я считаю соответствующим кодом из gdal2tiles.py:

                    # Scaling by PIL (Python Imaging Library) - improved Lanczos
                    array = numpy.zeros((querysize, querysize, tilebands), numpy.uint8)
                    for i in range(tilebands):
                            array[:,:,i] = gdalarray.BandReadAsArray(dsquery.GetRasterBand(i+1), 0, 0, querysize, querysize)
                    im = Image.fromarray(array, 'RGBA') # Always four bands
                    im1 = im.resize((tilesize,tilesize), Image.ANTIALIAS)
                    if os.path.exists(tilefilename):
                            im0 = Image.open(tilefilename)
                            im1 = Image.composite(im1, im0, im1) 
                    im1.save(tilefilename,self.tiledriver)

Любая идея, как сделать так, чтобы границы не было, если не считать открытия соответствующих сгенерированных файлов изображений плитки в редакторе изображений и установки прозрачных соответствующих пикселей?

Я подозреваю, что ответ заключается в том, чтобы найти какой-то способ представления прозрачных пикселей, чтобы сглаживание игнорировало их для целей выборки.

Обновление: возможно, он не получил никаких наград за элегантность или производительность, но я думаю, что я почти достиг цели. Конечно, последние несколько ярдов также являются самыми сложными.

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

Вот код с этими изменениями:

                # Scaling by PIL (Python Imaging Library) - improved Lanczos
                array = numpy.zeros((querysize, querysize, tilebands), numpy.uint8)
                for i in range(tilebands):
                        array[:,:,i] = gdalarray.BandReadAsArray(dsquery.GetRasterBand(i+1), 0, 0, querysize, querysize)
                im = Image.fromarray(array, 'RGBA') # Always four bands
                im1 = im.resize((tilesize,tilesize), Image.BICUBIC)
                if os.path.exists(tilefilename):
                        im0 = Image.open(tilefilename)
                        im1 = Image.composite(im1, im0, im1)
                im1AsArray = numpy.array(im1)
                alpha = im1AsArray[:,:,3]
                semiTransparentIndices = alpha < 255
                alpha[semiTransparentIndices] = 0
                im1AsArray[:,:,3] = alpha
                im1 = Image.fromarray(im1AsArray, 'RGBA')
                im1.save(tilefilename,self.tiledriver)

person Trott    schedule 13.05.2011    source источник
comment
Использование Image.NEAREST вместо Image.ANTIALIAS избавляет от границы, но, конечно, остальная часть плитки выглядит совершенно ужасно....   -  person Trott    schedule 14.05.2011
comment
Изменение БИКУБИЧЕСКОГО на БИЛИНЕЙНОЕ помогло. Думаю, я сам отвечу на свой вопрос.   -  person Trott    schedule 14.05.2011


Ответы (1)


Ответ заключается в том, чтобы изменить передискретизацию на БИЛИНЕЙНУЮ (а не БИКУБИЧЕСКУЮ, что я пробовал в обновлении, опубликованном на вопрос), а затем обязательно изменить любые полупрозрачные пиксели на полностью прозрачные пиксели.

Как я уже говорил в обновлении, сделанные здесь модификации кода могут не получить никаких наград за элегантность или производительность, но они работают. Вот что нужно изменить в исходном опубликованном фрагменте из gdal2tiles.py:

            # Scaling by PIL (Python Imaging Library) - improved Lanczos
            array = numpy.zeros((querysize, querysize, tilebands), numpy.uint8)
            for i in range(tilebands):
                    array[:,:,i] = gdalarray.BandReadAsArray(dsquery.GetRasterBand(i+1), 0, 0, querysize, querysize)
            im = Image.fromarray(array, 'RGBA') # Always four bands
            im1 = im.resize((tilesize,tilesize), Image.BILINEAR)
            if os.path.exists(tilefilename):
                    im0 = Image.open(tilefilename)
                    im1 = Image.composite(im1, im0, im1)
            im1AsArray = numpy.array(im1)
            alpha = im1AsArray[:,:,3]
            semiTransparentIndices = alpha < 255
            alpha[semiTransparentIndices] = 0
            im1AsArray[:,:,3] = alpha
            im1 = Image.fromarray(im1AsArray, 'RGBA')
            im1.save(tilefilename,self.tiledriver)

Также обратите внимание, что приведенный выше код будет выполняться только в том случае, если вы передадите gdal2tiles.py флаг -r antialias. Да, верно: мы изменили код -r antialias, чтобы он не сглаживался. Но если у вас возникла та же проблема, что и у меня, и вы просто хотите найти решение, вот оно.

person Trott    schedule 14.05.2011
comment
Спасибо, я часами жонглировал параметрами, пытаясь избавиться от этой небольшой блуждающей полосы вывода. Ваше решение помогло мне пройти через это! - person Gene Black; 29.05.2021