Как разбить изображение на подизображения?

Я хотел бы разделить изображение на серию изображений размером 256x256 пикселей.

Единственный метод кодирования, о котором я подумал, - это нарисовать ROI 256x256 на изображении, а затем создать/обрезать новое изображение из области ROI. (Пожалуйста, смотрите код ниже.)

Number size_x, size_y
image img 
img := GetFrontImage()
getsize( img, size_x, size_y )
showimage( img )

number x, y
For( y=0; y+256<size_y; y+=256 )
{
    For ( x=0; x+256<size_x; x+=256 )
    {
         ROI EMROI = NewROI()
         EMROI.ROISetRectangle( x, y, 256, 256 )
         img.ImageGetImageDisplay(0).ImageDisplayAddROI( EMROI )
         image cropped=img[]
         showimage(cropped)
    }
}

Но есть две ошибки: скрипт рисует области интереса только в направлении X, а не в направлении Y, и всегда создает новое изображение только из первого области интереса. Есть ли лучший способ разделить изображения DM? Или как мне изменить свой код, чтобы добиться этого?


person together    schedule 12.12.2017    source источник


Ответы (2)


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

Да, есть лучший способ сделать это. Вы можете обратиться к любому подразделу данных напрямую, используя нотацию [ t, l, b, r ], в которой вы используете 4 числа для указания региона. t вверху, l слева, b внизу, r справа как в:

Кородинаты

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

Команда среза


Сценарий, который вы хотите, вероятно, будет вариантом следующего

// Create TestImage
number sx = 1024
number sy = 1024
image img := RealImage( "Test", 4, sx, sy )
img = itheta * sin( (iradius+icol)/iwidth * 50 * pi() )
img.ShowImage()

// Split up into N x M images
// Optional: Perform check for integer-values using mod-division (% operator)
number n = 2
number m = 4
number notExact = ( sx % n != 0 ) || ( sy % m != 0 ) 
if ( notExact ) 
    if ( !OKCancelDialog( "The image split is not an integer division. Continue?" ) ) 
        exit(0)

number bx = sx/n
number by = sy/m

for( number row = 0; row < m; row++ )
    for( number col= 0; col< n; col++ )
        {
            // We want the sub-rect. We could use [t,l,b,r] notation, but I prefer slice2()
            number x0 = col * bx
            number y0 = row * by
            image sub := img.Slice2( x0,y0,0, 0,bx,1, 1,by,1 ).ImageClone() // CLONE the referenced data to create a copy
            sub.SetName( img.GetName() + "__"+col+"_"+row )
            sub.ShowImage()
        }

Если что-то осталось непонятным, спрашивайте!

person BmyGuest    schedule 12.12.2017
comment
Большое спасибо за твою помощь. Похоже, что работает только с реальным изображением (созданное вами тестовое изображение является реальным изображением). Я помню, что есть команда для получения реальной части изображения, но я не могу найти ее с помощью поиска в файле справки DM. Что такое код? Спасибо еще раз! - person together; 20.12.2017
comment
Можем ли мы пересмотреть этот скрипт, чтобы эта функция работала для изображения, которое предоставили клиенты (получить изображение спереди, тип изображения может не быть реальным изображением)? Спасибо, - person together; 20.12.2017
comment
@together Я думаю, что это должно работать с getfrontimage сразу. Переменные «Image», как правило, не зависят от типа, как и команды среза или клонирования. Существует очень мало ситуаций, когда требуется определенный тип (БПФ — это одно, бинарная морфология — другое). - person BmyGuest; 20.12.2017
comment
@together команды для преобразования сложного в реальное - это «настоящее» и «воображаемое». Я думаю, вы найдете их в справке F1 в разделе «ссылки». - person BmyGuest; 20.12.2017

Это ответ относительно того, что не так с вашим сценарием:

Вы неправильно используете команду ROISetRectangle.

Параметрами команды являются не X, Y, высота, ширина, а та же нотация сверху/слева/снизу/справа, которую я описал в другом ответе для [t,l,b,r] обозначение.

Ваш скрипт действительно будет работать, если вы замените одну строку на:

EMROI.ROISetRectangle( y, x, y + 256, x + 256 )

Нет необходимости использовать «визуальные» ROI для того, что вы хотите. (см. другой ответ)

Вместо [] для указания визуальной области интереса можно использовать [t,l,b,r] для прямого указания региона. Обратите внимание, что вы также можете добавить ROI, который вы добавили, с помощью простой команды:

img.SetSelection( t, l, b, r )

с тем же значением t,l,b,r.

Используемые вами команды ImageDisplay и ROI являются командами «нижнего уровня», которые могут делать больше вещей. Вы используете их правильно, но вам не всегда нужно их использовать, если вы можете делать что-то с помощью более простых команд.

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

Вместо

number x
for( x=0; x<10; x++ )
{
}

Использовать

for( number x=0; x<10; x++ )
{
}

Будьте осторожны при копировании изображений. оператор = копирует только значения. Вы можете использовать оператор := для адресации любых данных или подданных (без дополнительной памяти), а затем использовать команду ImageClone() для создания точной копии, включая метаданные, такие как калибровки или теги.

Итак, в вашем сценарии вы можете использовать

image cropped := ImageClone( img[] )
person BmyGuest    schedule 12.12.2017