我正在使用 dm-script 来处理原始轮廓。我首先计算其一阶导数来检测边缘,然后让用户在导数图中选择这些边缘之间的区域。但是,我希望相同的选择框也同时出现在原始轮廓图中,以直观地指导用户。
目前,我的实现是使用复合函数来垂直堆叠两个图(原始剖面和导数剖面)。虽然可以工作,但是交互区域之间的同步感觉很麻烦,而且不太优雅。
在 DM 脚本中,是否有更好或更有效的方法来链接原始配置文件和其衍生图之间的交互式选择区域?
任何建议或代码示例都值得赞赏!
Class CMyHandleLegend
{
TagGroup CreateLegendTags(object self, CompoundDocument doc, number selectedCMDid)
{
TagGroup Legend = NewTagList();
for(number i = 0; i < doc.CompoundDocumentCountImageDisplays() - 1; i++)
{
ImageDisplay ithDisp = doc.CompoundDocumentGetImageDisplay(i);
string buttonName = ithDisp.ImageDisplayGetImage().ImageGetName();
number buttonCMDid = 10000 + ithDisp.ComponentGetCompoundID();
TagGroup button = NewTagGroup();
button.TagGroupSetTagAsUInt32("ID", buttonCMDid);
button.TagGroupSetTagAsString("Name", buttonName);
button.TagGroupSetTagAsBoolean("Selected", buttonCMDid == selectedCMDid);
Legend.TagGroupAddTagGroupAtEnd(button);
}
// Legend.TagGroupOpenBrowserWindow(0)
return Legend;
}
void GetIthDisplayInfo(object self, CompoundDocument doc, number i, number &compID, number &AR, string &name)
{
ImageDisplay ithDisp = doc.CompoundDocumentGetImageDisplay(i);
Image ithImg = ithDisp.ImageDisplayGetImage();
compID = ithDisp.ComponentGetCompoundID();
Result("\n" + compID)
number sx = ithImg.ImageGetDimensionSize(0);
number sy = ithImg.ImageGetDimensionSize(1);
AR = (0 < sy) ? sx / sy : 1;
AR = clip(AR, 0.5, 2);
name = ithImg.ImageGetName();
}
TagGroup CreateRowLayout(object self, CompoundDocument doc, number cmdID)
{
number rowH = 300;
TagGroup Layout = CreateCompoundDocumentLayoutTagGroup("CompoundDocument Example 2");
TagGroup row = Layout.CompoundDocumentLayoutAddRow(rowH);
TagGroup row2 = Layout.CompoundDocumentLayoutAddRow(rowH);
number iCompID, iAR;
string iName;
number nImgD = doc.CompoundDocumentCountImageDisplays();
for(number i = 0; i < nImgD; i++)
{
self.GetIthDisplayInfo(doc, i, iCompID, iAR, iName);
if ((iCompID + 10000) == cmdID)
row.CompoundDocumentLayoutAddColumnAsImage(rowH * iAR, iName, iCompID);
if ((iCompID + 10000) == (cmdID + 1))
row2.CompoundDocumentLayoutAddColumnAsImage(rowH * iAR, iName, iCompID);
}
Layout.TagGroupSetTagAsBoolean("Legend", 1);
Layout.TagGroupSetTagAsTagGroup("Buttons", self.CreateLegendTags(doc, cmdID));
return Layout;
}
void ChooseLayout(object self, CompoundDocument doc, number cmdID)
{
TagGroup Layout = self.CreateRowLayout(doc, cmdID);
//Layout.TagGroupOpenBrowserWindow(0);
doc.CompoundDocumentShow(Layout);
}
void HandleLegendButtonPressed(object self, number flags, CompoundDocument doc, number cmdID)
{
Result("\n Received button message from: " + doc.ImageDocumentGetName());
Result("\n Button ID: " + cmdID);
self.ChooseLayout(doc, cmdID);
}
}
Image absolute_first_derivative(Image in)
{
// Edge detected at the peak (maximum absolute value) of the first derivative curve
Number size_x, size_y, origin, scale
String units
Image out
in.ImageGetDimensionCalibration(0, origin, scale, units, 0)
in.GetSize(size_x, size_y)
if (size_y != 1) Result("Only compatible with 1D image")
out := RealImage("first_derivative", 4, size_x, size_y)
out = abs(in[icol + 1, irow] - in[icol, irow])
//out[0, 0] = 0
//out[size_x - 1, 0] = 0
out.ImageSetDimensionCalibration(0, origin, scale, units, 0)
return out
}
void ShowLegendCompoundDocument()
{
CompoundDocument doc = NewCompoundDocument("CompoundDoc Example");
image img1 := RealImage("test", 4, 200);
img1 = 100
img1[0,0,1,50] = 50
img1[0,150,1,200] = 50
Image img2 := absolute_first_derivative(img1)
Image img3 = img1
Image img4 := absolute_first_derivative(img3)
img1.SetName("test 1")
img2.SetName("test 2")
img3.SetName("test 3")
img4.SetName("test 4")
doc.ImageDocumentAddImageDisplay(img1.ImageCreateImageDisplay(-2));
doc.ImageDocumentAddImageDisplay(img2.ImageCreateImageDisplay(-2));
doc.ImageDocumentAddImageDisplay(img3.ImageCreateImageDisplay(-2));
doc.ImageDocumentAddImageDisplay(img4.ImageCreateImageDisplay(-2));
object obj = Alloc(CMyHandleLegend);
number listenID = doc.CompoundDocumentAddListener(obj, "compounddocument_buttonpressed:HandleLegendButtonPressed");
obj.ChooseLayout(doc, 10008);
}
ShowLegendCompoundDocument();