2016-10-27 4 views
1

Nachdem ich eine kreisförmige ROI in einem Bild erstellt habe, wie kann ich die Informationen (Durchschnitt, Standardabweichung, Varianz) aus dieser Bildregion mithilfe eines Skripts ermitteln?Wie kann ich mit dem dm-Skript Informationen aus einem kreisförmigen ROI abrufen?

Kann ich die Position in der Circular-ROI mit dem Originalbild verknüpfen?

+0

Beziehen Sie sich auf das GMS 3-Feature "oval ROI" oder auf die ovalen Annotationen (auch aus früheren GMS-Versionen)? – BmyGuest

+0

Ihre zweite Frage ist unklar. Was meinst du mit "Link die Position"? Ein ROI ist nur eine Sammlung von Koordinaten. Sie können diese aus einer ROI lesen (d. H. Die Mitte finden) und die ROI auf einige setzen (d. H. Eine ROI in eine Position verschieben), wenn Sie das fragen. – BmyGuest

Antwort

1

Diese Aufgabe ist leider nicht so geradlinig und einfach wie man hoffen würde.

Während Scripting eine bequeme Verknüpfung unterstützt, um Bildoperationen auf rechteckige ROIs zu beschränken (mit der Notation img[]), gibt es für irreguläre ROIs nichts Vergleichbares.

In diesem Fall muss man manuell eine Binärmaske einer ROI erstellen und die gewünschten Operationen manuell ausführen. Das Beispielskript unten in diesem Beitrag zeigt, wie der Durchschnittswert einer unregelmäßigen ROI berechnet werden kann.

  • CreateImageWithROI() Erzeugt ein Testbild mit zwei ROIs auf ihn
  • GetFirstIrregularROIOfImage() gibt nur die erste gefunden, unregelmäßige ROI eines Bild
  • GetROIMean() ist das tatsächliche Beispiel

Der Befehl ROIAddToMask() verwendet wird um die Maske zu erstellen. Beachten Sie, dass es auch einen ähnlichen Befehl ist, die die Aktion mit alle ROIs einer Bildanzeige auf einmal durchführen würde: ImageDisplayAccumulateROIsToMask()

Irregular masking

So weit, so gut.

Es stellt sich jedoch heraus, dass die neu eingeführte Circular ROIs noch nicht unterstützen die Maskenerzeugungs richtig Befehle (Getestet mit GMS 3.1).

Stattdessen verwenden sie immer das Begrenzungsrechteck des ROI:

Creating mask from ROIs

Es ist daher notwendig, auch nur einen Schritt zurück zu gehen und den ROI Koordinaten lesen manuell eine Maske von ihm zu erstellen. Rufen Sie die Bounding-Box des ROI ab und erstellen Sie eine Maske mit einem icol und irow Ausdruck für eine Ellipse.Im Beispiel unten:

  • GetFirstOvalROIOfImage() gibt nur die erste gefunden, oval ROI ein Bild
  • MyAddOvalROIToMask() ist die manuelle Maskenerstellung für oval ROIs

Final example


Beispiel code:

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) 
+1

Vielen Dank für Ihre Hilfe. Ich kann diese Tipps in meiner Datenverarbeitung verwenden. –

+0

BTW, die gleiche Methode würde auch für runde Annotationen (in GMS 2 und früher) funktionieren, so dass man auch in dieser Situation "zirkuläre ROIs" bekommen kann. – BmyGuest

Verwandte Themen