отображать значения полярного серого в матрице без интерполяции каждого цикла for

У меня есть матрица со значениями серого между 0 и 1. Для каждой записи в матрице существуют определенные полярные координаты, которые указывают положение значений серого. У меня уже есть значения Theta и Rho (полярные), оба в отдельных матрицах 512×960. И значения оттенков серого (в матрице с именем C) для каждой комбинации Theta и Rho. У меня то же самое для X и Y, так как я просто использую pol2cart для трансформации. Проблема в том, что я не могу напрямую построить эти значения, поскольку они еще не помещаются в «ячейки» новой матрицы.

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

Один из примеров того, как может выглядеть одно из этих преобразований:

введите здесь описание изображения

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

Для каждого набора данных у меня есть сотни таких матриц, поэтому я хотел бы сделать код более эффективным.

Предыстория: сейчас я использую TriScatteredInterp для интерполяции. Мы также пробовали scatteredInterpolant, но он медленнее. Я также разместил связанный вопрос, но решил разделить два возможных решения, потому что решение, которое я прошу здесь, также применимо к коду, отличному от MATLAB, и, вероятно, будет быстрее и обеспечит более плавное (без непрерывного появления фигур) выполнение кода.


person BramMooij    schedule 12.05.2016    source источник
comment
Пожалуйста, не стесняйтесь попросить меня сделать вопрос более ясным. Я немного пытался прояснить проблему, но я очень хочу улучшить вопрос и привести примеры (где было бы предпочтительнее, чтобы пример был хорошо описан).   -  person BramMooij    schedule 12.05.2016
comment
Не ответ, но, возможно, это вам немного поможет: если вы посмотрите на источник функции interp2 (при условии, что вы используете это?), Есть ли какие-то шаги, которые вы можете пропустить, а затем сделать свою собственную реализацию, которая использует это? Однако я не уверен, что это возможно.   -  person Bernhard    schedule 12.05.2016
comment
Спасибо за комментарий. Это кажется хорошей идеей, я обязательно посмотрю на это. Конечно, ваш комментарий остается в силе для любой другой функции интерполяции, которую я использую.   -  person BramMooij    schedule 12.05.2016
comment
Что ж, рано или поздно вы столкнетесь со встроенной функцией, которая лишь перечисляет какие-то инструкции, но не имеет фактического источника.   -  person Bernhard    schedule 12.05.2016
comment
Я пытаюсь понять, как это работает в interp2, потому что исходный код для этого, похоже, открыт. Если я попытаюсь открыть код разбросанного Interpolant, я просто получу файл справки. Однако interp2 еще не работает для моих входных данных, поэтому я пытаюсь исправить код так, чтобы он работал. Я доложу, когда это будет закончено (к сожалению, я не могу тратить на это слишком много времени, так как это побочное направление моей работы). В то же время, если у кого-то есть другие предложения, я с нетерпением жду их.   -  person BramMooij    schedule 18.05.2016
comment
Итак, что такое X и Y, потому что вы говорите, что это полярные координаты? Какой угол, а какой радиус? Или X и Y уже преобразованы в декартовы координаты?   -  person Rody Oldenhuis    schedule 21.11.2016
comment
Отсортированы или реплицированы ли каким-либо образом X и `Y? ... вы, возможно, лучше всего опубликуете несколько простых входных данных 5 × 5, с которыми мы можем поиграть.   -  person Rody Oldenhuis    schedule 21.11.2016
comment
#Роди Спасибо за ваш комментарий. Я постараюсь опубликовать несколько простых примеров завтра. Тем временем я изменил вопрос, чтобы сделать его более ясным. У меня полярные координаты или декартовые. Что для вас полезнее.   -  person BramMooij    schedule 21.11.2016
comment
OK. Координаты расположены регулярно или разбросаны?   -  person Rody Oldenhuis    schedule 21.11.2016
comment
Кроме того, есть ли какая-то причина полагать, что межкоординатные значения цвета связаны с большим количеством координат, чем просто с ближайшими соседями? Например, ожидается ли, что цветовая прогрессия будет следовать какой-то функции θ и ρ?   -  person Rody Oldenhuis    schedule 21.11.2016
comment
Значения регулярно расположены в тета и регулярно расположены в ро. Также см. соответствующий вопрос для получения дополнительной информации о том, для чего я хочу его использовать. stackoverflow.com/q/37170450/5569238 . Ближайший сосед достаточно хорош. Значения - пиксели. Они не будут на 100% независимыми вблизи rho=0, но они должны быть при более высоких значениях rho. Они достаточно самостоятельны, чтобы их не нужно было принимать во внимание.   -  person BramMooij    schedule 21.11.2016
comment
Возможно, у вас есть набор инструментов для обработки изображений? Потому что imresize больше похоже на то, что вы хотите   -  person Rody Oldenhuis    schedule 21.11.2016
comment
У меня есть набор инструментов для обработки изображений. Проблема в том, что у меня есть эти значения, но они не помещаются в нормальную матрицу, а значит, не составляют изображения. Или есть способ использовать imresize со значениями, которые не составляют изображение? (У меня есть значения x, значения y и значения интенсивности отдельно, они регулярно расположены в тета и регулярно расположены в ро)   -  person BramMooij    schedule 22.11.2016


Ответы (1)


Использование набора инструментов для обработки изображений

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

Я вижу только одну проблему: упаковка. Очевидно, что θ = 2π = 0, но MATLAB этого не знает. Насколько я знаю, нет простого способа сообщить об этом MATLAB.

Почему это важно? Проще говоря, межпиксельная интерполяция использует информацию от ближайших N соседей для поиска промежуточных цветов, при этом N зависит от ядра интерполяции. Делая это где-то в середине изображения, проблем нет, но на краях MATLAB должен знать, что левый край равен правому краю. Это не стандартная обработка изображений, и я не знаю ни одной функции, способной на это.

Реализация

Теперь, если игнорировать проблему упаковки, это один из способов сделать это:

function resize_polar()

    %% ORIGINAL IMAGE
    % ==========================================================================

    % Some random greyscale data
    C = double(rgb2gray(imread('stars.png')))/255;

    % Your current size, and desired size    
    sz_x = size(C,2);    new_sz_x = 1024;
    sz_y = size(C,1);    new_sz_y = 1024;

    % Ranges for teat and rho;  
    % replace with your actual values
    rho_start = 0;     theta_start = 0;
    rho_end   = 10;    theta_end   = 2*pi;

    % Generate regularly spaced grid;
    theta = linspace(theta_start, theta_end, sz_x);
    rho   = linspace(rho_start,   rho_end,   sz_y);

    [theta, rho] = meshgrid(theta,rho);


    % Make plot of generated data
    plot_polar(theta, rho, C, 'Original image');

    % Resize data
    [theta,rho,C] = resize_polar_data(theta, rho, C, [new_sz_y new_sz_x]);

    % Make plot of generated data
    plot_polar(theta, rho, C, 'Rescaled image');

end


function [theta,rho,data] = resize_polar_data(theta,rho,data, new_dims)

    % Create fake RGB image cube 
    IMG = cat(3, theta,rho,data);

    % Rescale as if theta and rho are RG color data in the RGB
    % image cube
    IMG = imresize(IMG, new_dims, 'nearest');

    % Split up the data again
    theta = IMG(:,:,1);
    rho   = IMG(:,:,2);
    data  = IMG(:,:,3);

end

function plot_polar(theta, rho, data, label)

    [X,Y] = pol2cart(theta, rho);

    figure('renderer', 'opengl')
    clf, hold on

    surf(X,Y,zeros(size(X)), data, ...
         'edgecolor', 'none');     
    colormap gray

    title(label);

end

Использованные и нанесенные изображения:

Удивительно нарисованное изображение PNG 512 × 960 звезды, сделанные с помощью MS Paint

Оригинал

Масштабированное изображение

Теперь они выглядят одинаково (на самом деле не удалось придумать более подходящее изображение), поэтому вам придется поверить мне, что 512 × 960 действительно было масштабировано до 1024 × 1024 с интерполяцией ближайшего соседа.

Вот некоторые тайминги фактической операции imresize() для некоторых простых ядер:

nearest : 0.008511 seconds.
bilinear: 0.019651 seconds.
bicubic : 0.025390 seconds.  <-- default kernel

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

Упаковка

Если проблема упаковки действительно важна для вас, вы можете изменить приведенную выше функцию, чтобы сделать следующее:

  • сначала измените масштаб изображения с помощью imresize(), как раньше
  • горизонтально объединить вторую половину данных в градациях серого и первую половину. Это означает, что вы меняете местами первую и вторую половины, чтобы левый и правый края (0 и 2π) соприкасались посередине.
  • масштабируйте это промежуточное изображение с помощью imresize()
  • Извлеките центральную вертикальную полосу масштабированного промежуточного изображения.
  • разделить его на две полосы одинаковой ширины
  • и замените краевые полосы выходного изображения двумя полосами, которые вы только что создали.

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

person Rody Oldenhuis    schedule 22.11.2016