【问题标题】:How to rotate Annotations when converting HDF5 files to dm3?将 HDF5 文件转换为 dm3 时如何旋转注释?
【发布时间】:2021-11-20 16:01:20
【问题描述】:

我正在使用 Tore Niermann 的插件 (gms_plugin_hdf5) 将 Velox 文件 (HDF5) 转换为 .dm3 文件以读取字符串。 HDF5 文件的注释也需要传输到 .dm3 文件。 HDF5 文件可以任意角度旋转。但是从 hdf5 文件中读取的标注的位置坐标是对应于没有旋转的图像。 我发现注释没有随着旋转图像移动。我不得不重新计算每个注释的位置坐标。对于框或椭圆等注释不方便。我需要在旋转图像时提取最大区域。所以图像大小会随着旋转角度而变化。那么旋转注释有更好的解决方案吗?谢谢。 这是我的脚本中的一个示例函数。因为太长了,我没有全部附上。

image GetAnnotations(Taggroup names, string filename, string name, Taggroup Annotations, Image VeloxImg, number Angle)
{
number i, j, imagex, imagey, xscale, yscale
String Displaypath, AnnotationStr, DisplayStr, units
taggroup attr = NewTagList()
getsize(VeloxImg, imagex, imagey)
number centerx=imagex/2
number centery=imagey/2
getscale(veloximg, xscale, yscale)
units=getunitstring(veloximg)
component imgdisp=imagegetimagedisplay(VeloxImg, 0)
    For (j=0; j<TagGroupCountTags(Annotations); ++j)
        {
        TagGroupGetIndexedTagAsString(Annotations, j, AnnotationStr)
        string AnnotPath=h5_read_string_dataset(filename, AnnotationStr)
        string AnnotDataPath=GetValueFromLongStr(AnnotPath, "dataPath\": \"", "\"")
        AnnotDataPath=ReplaceStr(AnnotDataPath, "\\/", "\/")
        string AnnotLabel=GetValueFromLongStr(AnnotPath, "label\": \"", "\"")
        string AnnotDrawPath=h5_read_string_dataset(filename, AnnotDataPath)
        image img := RealImage( "", 4, 1, 1 )
        TagGroup AnnoTag=alloc(MetaStr2TagGroup).ParseText2ImageTag(AnnotDrawPath, img )
        deleteimage(img)
        string AnnotDrawType=TagGroupGetTagLabel(AnnoTag,0)
        //AnnoTag.TagGroupOpenBrowserWindow( "AnnotationsTag", 0 )
        
        if (AnnotDrawType=="arrow")
        {
        number p1_x,p1_y,p2_x,p2_y
        TagGroupGetTagAsNumber(AnnoTag, "arrow:p1:x", p1_x)
        TagGroupGetTagAsNumber(AnnoTag, "arrow:p1:y", p1_y)
        TagGroupGetTagAsNumber(AnnoTag, "arrow:p2:x", p2_x)
        TagGroupGetTagAsNumber(AnnoTag, "arrow:p2:y", p2_y)
        //VeloxImg.CreateArrowAnnotation( p1y, p1x, p2y, p2x )
        number p1_x_new=(p1_x-0.5)*cos(Angle)+(p1_y-0.5)*sin(Angle)+0.5
        number p1_y_new=-(p1_x-0.5)*sin(Angle)+(p1_y-0.5)*cos(Angle)+0.5
        number p2_x_new=(p2_x-0.5)*cos(Angle)+(p2_y-0.5)*sin(Angle)+0.5
        number p2_y_new=-(p2_x-0.5)*sin(Angle)+(p2_y-0.5)*cos(Angle)+0.5
        result(p1_x+" "+p1_y+" new "+p1_x_new+" "+p2_y_new+"\n")
        
        component arrowAnno=newarrowannotation(p1_y_new*imagey, p1_x_new*imagex, p2_y_new*imagey, p2_x_new*imagex)
        arrowAnno.ComponentSetForegroundColor( 1, 0 , 0 )
        arrowAnno.ComponentSetDrawingMode( 2 )
        imgdisp.ComponentAddChildAtEnd( arrowAnno )
        }

【问题讨论】:

  • HDF5 是 GMS 3.5 中直接支持的文件格式 - 但我认为这不能解决您的直接问题。 (因为 GMS 不支持在不将图像对象重新采样到新的屏幕轴对齐网格的情况下“旋转”它们。)

标签: dm-script


【解决方案1】:

不直接回答您的问题,但您可能仍然感兴趣: 虽然 GMS 不支持注释的旋转(矩形、椭圆形、文本、图像显示...),但它支持 ROI 的旋转属性。因此,也许您可​​以只在应用程序中使用 rect-ROI 和椭圆形 ROI 而不是注释。 示例(没关系,我错误地进行了移位计算):


image test := realImage("Test",4,512,512)
test= abs(sin(6*PI()*icol/iwidth))*abs(cos(4*PI()*irow/iheight*iradius/150))
test.showimage()
imageDisplay disp = test.ImageGetImageDisplay(0)
ROI box = NewROI()
box.RoiSetRectangle(46,88,338,343)
box.RoiSetVolatile(0)
ROI oval = NewROI()
oval.ROISetOval(221,226,287,254)
oval.RoiSetVolatile(0)
disp.ImageDisplayAddROI(box)
disp.ImageDisplayAddROI(oval)


number rot_deg = 8
image rot := test.rotate( pi()/180*rot_deg)
rot.ShowImage()
imageDisplay disp_rot = rot.ImageGetImageDisplay(0)
ROI box_rot = box.ROIClone()
ROI oval_rot = oval.ROIClone()
disp_rot.ImageDisplayAddROI(box_rot)
disp_rot.ImageDisplayAddROI(oval_rot)

number shift_x = (rot.ImageGetDimensionSize(0)-test.ImageGetDimensionSize(0)) / 2
number shift_y = (rot.ImageGetDimensionSize(1)-test.ImageGetDimensionSize(1)) / 2

number t,l,b,r
box_rot.ROIGetRectangle(t,l,b,r)
box_rot.ROISetRectangle(t+shift_y,l+shift_x,b+shift_y,r+shift_x)

oval_rot.ROIGetOval(t,l,b,r)
oval_rot.ROISetOval(t+shift_y,l+shift_x,b+shift_y,r+shift_x)

box_rot.ROISetRotationAngle( rot_deg )
oval_rot.ROISetRotationAngle( rot_deg )

【讨论】:

  • 感谢您的帮助。这就是我需要的。虽然旋转仅支持 Rect-ROI 和 Oval-ROI,但我将使用它们而不是注释。我将重新计算其他注释的坐标系。非常感谢。
【解决方案2】:

如果我理解正确,那么您的源数据(HDF5)存储图像(二维数组?)加上旋转角度,但是(未旋转)图像坐标系中的注释?那么原始软件中的源数据是如何显示的呢? (它显示的是一个旋转的矩形图像吗?)

GMS 不支持旋转图像显示(作为对象),因此也不支持旋转注释。坐标系始终与屏幕轴正交对齐。因此在“旋转”图像时需要插值。为新网格重新计算数据值。

如果您不需要在输入后调整注释,您可以做的一件可能的事情是在导入前旋转后创建“显示”图像,然后使用“刻录”注释旋转图像”。 不过,这显然只适用于创建“最终显示图像”。

image before := realImage("Test",4,512,512)
before = abs(sin(6*PI()*icol/iwidth))*abs(cos(4*PI()*irow/iheight*iradius/150))

before.showimage()
before.ImageGetImageDisplay(0).ComponentAddChildAtEnd(NewArrowAnnotation(30,80,60,430))
before.ImageGetImageDisplay(0).ComponentAddChildAtEnd(NewArrowAnnotation(30,80,206,240))
before.ImageGetImageDisplay(0).ComponentAddChildAtEnd(NewOvalAnnotation(206,220,300,256))


// Create as-displayed image
Number t,l,b,r,ofx,ofy,scx,scy
before.ImageGetOrCreateImageDocument().ImageDocumentGetViewExtent(t,l,b,r)
before.ImageGetOrCreateImageDocument().ImageDocumentGetViewToWindowTransform(ofx,ofy,scx,scy)
image asShown := before.ImageGetOrCreateImageDocument().ImageDocumentCreateRGBImageFromDocument(round((r-l)*scx),round((b-t)*scy),0,0)
asShown.ShowImage()

number angle_deg = 8
image rotated := asShown.Rotate( angle_deg/180*PI() )
rotated.ShowImage()

【讨论】:

  • 感谢您的回答。您清楚地了解我的问题,并对不清楚的描述感到抱歉。这是一个绝妙的方法。但实际情况下旋转角度可能为 180°。因此,在这种情况下,文本将无法正确显示。所以坐标系变换更适合我。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2017-05-20
  • 2021-05-03
  • 2019-07-15
  • 2016-12-13
  • 2023-03-08
  • 1970-01-01
  • 2023-03-15
  • 2015-08-30
相关资源
最近更新 更多