Эта задача, к сожалению, не так проста и проста, как хотелось бы.
Хотя сценарии поддерживают удобный ярлык для ограничения операций изображения с прямоугольными ROI (с использованием нотации img[]
), нет ничего подобного для нерегулярных ROI.
В таком случае необходимо вручную создать двоичную маску ROI и выполнить требуемые операции вручную. Пример сценария внизу этого сообщения показывает, как можно вычислить среднее значение нерегулярного ROI.
CreateImageWithROI()
Создает тестовое изображение с двумя областями на нем
GetFirstIrregularROIOfImage()
просто возвращает первый найденный, нерегулярный ROI изображений
GetROIMean()
является фактическим примером
Команда ROIAddToMask()
используется для создания маски. Обратите внимание, что существует также аналогичная команда, которая будет выполнять действия с всех трансформирования на графическом дисплее сразу: ImageDisplayAccumulateROIsToMask()
До сих пор, так хорошо.
Однако, оказывается, что вновь введенные Круговые трансформировании еще не поддерживают маски создания команды правильно (Испытано с GMS 3.1).
Вместо этого, они всегда используют ограничивающий прямоугольник ROI:
, поэтому необходимо пройти еще один шаг назад и прочитать координаты ROI, чтобы создать маску из него вручную. Получите ограничительную рамку ROI и создайте маску с помощью выражения icol
и irow
для эллипса.В приведенном ниже пример:
GetFirstOvalROIOfImage()
просто возвращает первую найденную, овальную ROI изображений
MyAddOvalROIToMask()
является ручным созданием маски для овальной трансформировании
Примера код:
image CreateImageWithROI()
{
// Create and show image
number sx = 256, sy = 256
image img := RealImage("Image", 4, sx, sy)
img = sin(0.1 * iradius) * cos(7 * itheta)
img.ShowImage()
// Create an irregular, closed ROI
ROI myIrRoi = NewROI()
myIrRoi.ROIAddVertex(0.3 * sx, 0.1 * sy)
myIrRoi.ROIAddVertex(0.7 * sx, 0.2 * sy)
myIrRoi.ROIAddVertex(0.5 * sx, 0.6 * sy)
myIrRoi.ROIAddVertex(0.1 * sx, 0.8 * sy)
myIrRoi.ROISetIsClosed(1)
myIRRoi.ROISetVolatile(0)
// Create an oval ROI
ROI myOvalROI = NewROI()
myOvalROI.ROISetOval(0.7 * sy, 0.7 * sx, 0.9 * sy, 0.8 * sx)
myOvalROI.ROISetVolatile(0)
// AddROIs
imageDisplay disp = img.ImageGetImageDisplay(0)
disp.ImageDisplayAddROI(myIRRoi)
disp.ImageDisplayAddROI(myOvalROI)
return img
}
ROI GetFirstIrregularROIOfImage(image img)
{
if (img.ImageIsValid())
{
if (0 != img.ImageCountImageDisplays())
{
imageDisplay disp = img.ImageGetImageDisplay(0)
number nRois = disp.ImageDisplayCountROIs()
for (number i = 0; i < nRois; i++)
{
ROI testROI = disp.ImageDisplayGetRoi(i)
number isIrregularClosed = 1
isIrregularClosed *= testROI.ROIIsClosed();
isIrregularClosed *= !testROI.ROIIsOval();
isIrregularClosed *= !testROI.ROIIsRectangle();
isIrregularClosed *= (2 < testROI.ROICountVertices());
if (isIrregularClosed)
return testROI
}
}
}
Throw("No irregular ROI found")
}
ROI GetFirstOvalROIOfImage(image img)
{
if (img.ImageIsValid())
{
if (0 != img.ImageCountImageDisplays())
{
imageDisplay disp = img.ImageGetImageDisplay(0)
number nRois = disp.ImageDisplayCountROIs()
for (number i = 0; i < nRois; i++)
{
ROI testROI = disp.ImageDisplayGetRoi(i)
if (testROI.ROIIsOval())
return testROI
}
}
}
Throw("No oval ROI found")
}
void MyAddOvalROIToMask(image img, ROI ovalROI)
{
number top, left, bottom, right
ovalROI.ROIGetOval(top, left, bottom, right)
number sx = (right - left)
number sy = (bottom - top)
number cx = sx/2 // Used as both center x coordiante and x radius!
number cy = sy/2 // Used as both center y coordiante and y radius!
// Create mask of just the rect area
image maskCut := RealImage("", 4, sx, sy)
maskCut = (((cx-icol)/cx)**2 + ((cy-irow)/cy)**2 <= 1) ? 1 : 0
// Apply mask to image
img[top, left, bottom, right] = maskCut
}
number GetROIMean(image img, ROI theRoi)
{
if (!img.ImageIsValid()) Throw("Invalid image in GetROIMean()")
if (!theRoi.ROIIsValid()) Throw("Invalid roi in GetROIMean()")
// Create a binary mask of "img" size using the ROI's coordinates
image mask = img * 0; // image of same size as "img" with 0 values
number sx, sy
img.GetSize(sx, sy)
// Oval ROIs are not supported by the command correctly
// Hence check and compute mask manually..
if (theROI.ROIIsOval())
MyAddOvalROIToMask(mask, theROI)
else
theROI.ROIAddToMask(mask, 0, 0, sx, sy)
if (TwoButtonDialog("Show mask?", "Yes", "No"))
mask.ShowImage()
// Do meanValue as sums of masked points
number maskedPoints = sum(mask)
number maskedSum
if (0 < maskedPoints)
maskedSum = sum(mask * img)/maskedPoints
else
maskedSum = sum(img)
return maskedSum
}
Result("\n Testing irregular and oval ROIs on image.\n")
image testImg := CreateImageWithROI()
ROI testROIir = GetFirstIrregularROIOfImage(testImg)
number ROIirMean = GetROIMean(testImg, testROIir)
Result("\n Mean value (irregular ROI): "+ ROIirMean)
ROI testROIoval = GetFirstOvalROIOfImage(testImg)
number ROIovalMean = GetROIMean(testImg, testROIoval)
Result("\n Mean value (oval ROI) : "+ ROIovalMean)
Вы имеете в виду функцию GMS 3 «овальная ROI» или овальные аннотации (также из предыдущих версий GMS)? – BmyGuest
Ваш второй вопрос непонятен. Что вы подразумеваете под «ссылкой на позицию»? ROI - это всего лишь совокупность координат. Вы можете прочитать те из ROI (т. Е. Найти центр) и установить ROI для некоторых (т. Е. Изменить рентабельность инвестиций в позицию), если это так, что вы просите. – BmyGuest