imagejimagej-macro

Randomly generate points in an Image in a selected ROI. (Image J macro)


I am trying to put n dots randomly on a selected ROI in an image using the macro;

Roi.getBounds(x,y,w,h);
count = 0;
while (count < n) { 
    roiManager( "select", 0 ); // select the first, "big" ROI
    x1 = random() * w + x;
    y1 = random() * h + y;
    if (selectionContains(x1, y1) == true ) { // if coordinates are inside the "big" ROI 
        makePoint(x1, y1); // generate random point
        roiManager("Add");// add the point to the ROI Manager
        count++; // ONLY increase count when point is added
    }
}

But now, I want a condition that I should not get (x,y) in a (x-1,y-1), (x+1,y+1) neighbourhood. How can I write ths in the code? (no 2 points should be closer by 1 pixel).


Solution

  • I added a function, that calculates the distance between your new point and all of your existing point (it actually calculates the square of the distance, but it doesn't really matter). Function returns true if the two points are neighbours and false if they are not.

    Roi.getBounds(x,y,w,h);
    count = 0;
    n=3;
    allx=newArray(n);  // creates array where all of the points will be stored
    ally=newArray(n);  // creates array where all of the points will be stored
    
    // function that calculates distance between all of the selected points
    function is_neighbour(array_x, array_y, x1, y1){
        for (elem=0; elem<array_x.length; elem++){
            x2 = array_x[elem];
            y2 = array_y[elem];
            distance = (x1 - x2)*(x1 - x2) + (y1-y2)*(y1-y2);
            if (distance < 3) return true;
            }
        return false;
        }
    
    while (count < n) { 
        roiManager( "select", 0 ); // select the first, "big" ROI
        x1 = random() * w + x;
        y1 = random() * h + y;
        if (selectionContains(x1, y1) == true ) { // if coordinates are inside the "big" ROI 
            if ( !is_neighbour(allx, ally, x1, y1 ) ){
                makePoint(x1, y1); // generate random point
                roiManager("Add"); // add the point to the ROI Manager
                allx[count] = x1; // add x1 to array of all x
                ally[count] = y1; // add y1 to array of all y
                count++; // ONLY increase count when point is added
            }         
        }
    

    Something in your code doesn't work for me, so I couldn't really test it. But the is_neighbour function works. Oh and I defined neighbour as all of the points that are in contact (even diagonally): neighbours

    If you are only interested in the light read ones, just change distance < 2 .