2013-05-04 3 views
0

Я хочу нанести произвольное double[][] на другое double[][] с различными измерениями. Значения результирующего массива должны вычисляться на основе входного массива с использованием бикубической интерполяции.Масштаб 2D-массива с использованием бикубической интерполяции

Я знаю, что это было сделано в обработке изображений на протяжении десятилетий, но мне не удалось найти библиотеку или хотя бы фрагмент рабочего кода, который работает для любого 2d-массива, а не для некоторых конкретных объектов изображения, поэтому я ' спрашиваю здесь.

Более конкретные требования:

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

double interpolate(double[][] grid3by3, double x, double y)` 

, где х и у от 0,0 до 1,0

Следующим шагом будет, конечно, чтобы облегчить этот процесс, поэтому 3x3 сетка выбирается для каждой точки автоматически, и я могу получить что-то вроде

`double[][] interpolate(double[][] input, int newWidth, int newHeight)` 

Это даст мне новый массив с указанными размерами, но с теми же границами, что и входной массив.

Где я на самом деле хочу, чтобы это:

`double[][] interpolate(double[][] input, int newWidth, int newHeight, 
         double minX, double minY, double maxX, double maxY)` 

Минимальное и максимальное значения определяют прямоугольник, так что я могу получить подмножество исходного массива, не обязательно нужно, чтобы начать или конец на точное значение индекса входного массива (например, угол может быть равен (5,3) или (5,25, 3,7), поэтому вы не можете просто отключить входной массив при некотором значении индекса). Этот ограничивающий прямоугольник станет границей нового массива, и значения будут интерполированы из входного массива.

Ой, а просто FYI: Речь идет о цифровых моделей рельефа, поэтому, пожалуйста, скажите мне, если мой подход в корне неверен, в первую очередь;)

+0

Ваш подход состоит в том, чтобы заявить, что вы хотите, а не как вы хотели бы, чтобы это произошло.Подкрепляя этот подход, я бы сказал, что было бы неплохо объявить класс, содержащий холст как частное свойство (double [] []). Ваша функция интерполяции, которую я переименовал бы в «resize» или «resizeBicubic», которая будет методом вашего класса canvas. Метод изменения размера изменит размер собственного холста, но может также вернуть новый холст. –

+0

Ну, вот о чем эта тема: я знаю, чего хочу, и знаю, что можно сделать в теории, но я не знаю, как ее реализовать. Если вы знаете библиотеку, которая решает одну из проблем или знает, как реализовать решение, я буду рад прочитать об этом. Мне действительно все равно, как вы называете функцию, или массив является частным или публичным свойством;) – Klamann

ответ

0

Просто хотел поделиться тем, как я решил проблему (или, вернее, Я не делал этого):

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

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

А вот мой обходной путь: Получить ImageJ и сделать что-то вроде этого:

// works all the same for: byte, short, int 
float[] myData;  
// create a new image. change 32 to 16 for short or 8 for byte 
ImageStack stack = ImageStack.create(width, height, 1, 32); 
stack.setPixels(myData, 1); 
ImageProcessor processor = new ImagePlus("", stack).getProcessor(); 
// crop and scale 
processor.setRoi(x, y, rwidth, rheight); 
ImageProcessor result = processor.crop().resize(newWidth, newHeight); 
// retrieve results 
float[] myScaledData = (float[]) result.getPixels(); 

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