【问题标题】:Catching the "Pixel outside the boundaries" exception?捕捉“边界外的像素”异常?
【发布时间】:2017-05-29 07:51:40
【问题描述】:

我有一张带有周期性排列的原子的图像。

我正在尝试编写一个脚本,通过在左上角原子上分配一个 ROI 来计算第一列中排列了多少原子,然后让脚本从左到右 扫描(列按列)。我的想法是,通过使用从左到右扫描的ROI,当它命中像素超出边界(这意味着,它超出图像),该脚本返回一行中的原子数,而不是给出错误输出“已引用图像边界外的像素”。

有没有什么办法可以让上面的案例写成脚本?

谢谢。

【问题讨论】:

    标签: exception pixel dm-script


    【解决方案1】:

    您可以捕获脚本代码抛出的任何异常,并使用

    自行处理
    Try(){ }
    Catch{ break; } 
    

    构造。但是,这不是解决您的问题的最佳解决方案。如果您知道图像的大小,那么您确实应该使用该知识来防止访问绑定之外的数据。使用Try{}Catch{} 最好留给那些“任何意外” 可能发生的情况,并且您仍然想处理问题。

    这是您问题的代码示例。

    number boxSize = 3
    
    number sx = 10
    number sy = 10
    image img := realImage( "Test", 4, sx, sy )
    img = random()
    
    // Output "sum" over scanned ROI area
    
    // Variant 1: Just scan -- Hits an exception, as you're moving out of range
    /*
    for( number j=0;j<sy;j++)
        for( number i=0;i<sx;i++)
            {
                Result("\n ScanPos: " + i +" / " + j )
                Result("\t SUM: "+ sum( img[j,i,j+boxSize,i+boxSize] ) );
            }
    */
    
    // Variant 2: As above, but catch exception to just continue
    for( number j=0;j<sy;j++)
        for( number i=0;i<sx;i++)
            {
                Result("\n ScanPos: " + i +" / " + j )
                Try
                {
                    Result( "\t SUM: "+ sum( img[j,i,j+boxSize,i+boxSize] ) );
                }
                catch
                {
                    Result( "\t ROI OUT OF RANGE" )
                    break;      // Needed in scripting, or the exception is re-thrown
                }
            }
    
    // Variant 3: (Better) Avoid hitting the exception by using the knowlede of data size
    for( number j=0;j<sy-boxSize;j++)
        for( number i=0;i<sx-boxSize;i++)
            {
                Result("\n ScanPos: " + i +" / " + j )
                Result("\t SUM: "+ sum( img[j,i,j+boxSize,i+boxSize] ) );
            }
    

    【讨论】:

    • 非常感谢您的回答!有一件事我不太明白。 “异常被重新抛出”是什么意思? @BmyGuest
    • 基本上,任何代码 (C++) 都可能遇到一些“意想不到的”麻烦。 (说除以零或其他任何东西。)在这样的时刻,“抛出异常”,基本上发送一条消息“有问题”。代码的另一部分“捕捉”了这一点并采取相应的行动 - f.e.提示错误信息。如果 no 代码捕获到异常,应用程序可能会简单地崩溃并关闭。 “没有债券”错误就是这样一个时刻——你要求程序访问一些不存在的内存!通常,“脚本引擎”会捕捉到这一点,并提示错误。如果您改为使用“Try{}Catch{}”,那么...
    • ..您自己可以“处理”如上所示的情况。但是,如果您不将“中断”放在 catch-loop 中,那么原始“异常”不会从队列中删除,并且 DM 脚本代码仍然提示您错误信息。试试上面没有“break”的代码。
    • 谢谢!我确实尝试了上面的代码,现在我明白了 re-thrown 的含义。但是当我在我的脚本中尝试 Try-Catch 的想法时,它并不顺利。当我让特定大小的 ROI moves atomic-column by atomic-column 时,当涉及到靠近图像侧面的最后一个原子列时(但不是在最后一个像素图像),脚本仍将运行并导致 ROI 最终出现在图像之外。请问上面的情况怎么处理?
    • 作为附加信息,我确实知道图像的大小,但 ROI 的 移动 并不固定。因此,当 ROI 位于最后一个原子列时;它不在图像的最后一个像素处。我没有让 ROI 保持 移动,因为它们前面有一些像素 ,我尝试让 ROI 停在最后一个原子列,即使最后一个原子列不在图像的最后一个像素处。你能帮帮我吗?
    【解决方案2】:

    要回答已接受答案的 cmets 中的问题: 您可以查询图像上的任何 ROI/选择,并使用此信息来限制迭代。 以下示例显示了这一点。它还显示了如何正确使用 ROI 对象,以获取选择以及添加新的 ROI。更多信息可在 F1 帮助中找到:

    脚本采用最前面的图像,上面只有一个选择。 然后它从左上角(以给定的步长)迭代选择并输出区域的总和值。最后,您可以选择将使用过的区域绘制为新的 ROI。

    ClearResults()
    
    // 1) Get image and image size
    image img := GetFrontImage()
    number sx = img.ImageGetDimensionSize(0)
    number sy = img.ImageGetDimensionSize(0)
    Result( "Image size: "+ sx + "x"+ sy+"\n")
    
    // 2) Get the size of the user-drawn selection (ROI)
    //  2a)
    //  If you are only dealing with the simple, user-drawn rectangle selections
    //  you can use the simplified code below instead.
    number t, l, b, r
    img.GetSelection(t,l,b,r)
    Result( "Marker coordinates (simple): ["+t+","+l+","+b+","+r+"]\n" )
    
    //  2b)
    //  Or you can use the "full" commands to catch other situations.
    //  The following lines check ROIs in a more general way.
    //  Not strictly needed, but to get you started if you want
    //  to use the commands outlined in F1 help section 
    //  "Scripting > Objects > Document Object Model > ROI Object"
    imageDisplay disp = img.ImageGetImageDisplay(0)
    if( 0 == disp.ImageDisplayCountROIs() )
        Throw( "No ROI on the image." )
    if( 1 < disp.ImageDisplayCountROIs() )
        Throw( "More than one ROI on the image." )
    
    ROI theMarker = disp.ImageDisplayGetROI(0)  // First (and only) ROI
    
    if ( !theMarker.ROIIsRectangle() )
        Throw( "ROI not a rectangle selection." )
    
    if ( !theMarker.ROIGetVolatile() )
        Throw( "ROI not voltaile." )            // Voltile = ROI disappears when another is drawn. Dashed outline.
    
    number top, left, bottom, right
    theMarker.ROIGetRectangle( top, left, bottom, right )
    Result( "Marker coordinates (ROI commands): ["+top+","+left+","+bottom+","+right+"]\n" )
    
    // 3) Iterate within bounds
    number roiWidth  = right - left
    number roiHeight = bottom - top
    
    number roiXStep = 100   // We shift the ROI in bigger steps
    number roiYStep = 100   // We shift the ROI in bigger steps
    if ( !GetNumber( "The ROI is " + roiWidth + "pixels wide. Shift in X?", roiWidth, roiXStep ) )
        exit(0)
    if ( !GetNumber( "The ROI is " + roiHeight + "pixels heigh. Shift in Y?", roiHeight, roiYStep ) )
        exit(0)
    
    for ( number j = 0; j<sy-roiHeight; j+=roiYStep )
        for ( number i = 0; i<sx-roiWidth; i+=roiXStep )
        {
            Result( "Sum at "+i+"/"+j+": " + sum( img[j,i,j+roiHeight,i+roiWidth] ) + "\n" )
        }
    
    // 4) If you want you can "show" the used positions.
    if ( !TwoButtonDialog("Draw ROIs?","Yes","No") )
        exit(0)
    
    
    for ( number j = 0; j<sy-roiHeight; j+=roiYStep )
        for ( number i = 0; i<sx-roiHeight; i+=roiXStep )
        {
            roi markerROI = NewRoi()
            markerROI.ROISetRectangle( j, i, j+roiHeight, i+roiWidth )
            markerROI.ROISetVolatile(0)
            markerROI.ROISetColor(0,0.4,0.4)
            markerROI.ROISetMoveable(0)
            markerROI.ROISetLabel( ""+i+"/"+j ) // Start with "" to ensure the parameter is recognized as string
    
            disp.ImageDisplayAddRoi( markerROI )
        }
    

    【讨论】:

      猜你喜欢
      • 2012-01-10
      • 2010-10-14
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      相关资源
      最近更新 更多