1

im using skimage to create region for an image

from skimage.measure import regionprops
from skimage import measure
label_image = measure.label(binary_car_image)
for region in regionprops(label_image):
  ...

in some cases those region can be intersected with each other . as you can see in the image bellow:

enter image description here

in this image there is two regions , but thet intersect with each other. my need is to merge them to a one region instead of two in this case.

i found this so link , two check if they intersect with each other. so my need is to merge those two regions ( or maybe more then 2 in some cases ) to only one region .

thanks

MoxGeek
  • 458
  • 6
  • 17
  • 2
    Get the bounding box (corner) coordinates of each rectangle. Then get the min and max x and min and max y coordinates from the set. Use that to define a new rectangle that is the bounding box of both. – fmw42 Jul 28 '20 at 23:21

2 Answers2

2

Just as fmw42 suggested, do something like this (this is untested C++ code, but it should give you an idea of what to do):

First, set some initial values:

int maxX = 0; // width of the contour + minimum x
int minX = 5000; // minimum x (big value)
int minY = 5000; // height of the contour + min y (big value)
int maxY = 0; // min y

Then, loop through all your contours, and for each contour compute its bounding box via boundingRect. The contours are stored in the vector contours, which in C++ is a vector of vectors of cv::Points.

//loop through all the contours:    
for( int i = 0; i < (int)contours.size(); i++ ){

    //process the outter most contours only:
    if ( hierarchy[i][3] == -1 ) {

        //get the simple bounding box:
        cv::Rect contourRect = cv::boundingRect( contours[i] );

        //get the coordinates of the bounding box for x:
        int countourMaximumX = contourRect.x + contourRect.width;
        if ( countourMaximumX > maxX ){
            maxX = countourMaximumX;
        }

        if ( contourRect.x < minX ){
            minX = contourRect.x;
        }

        //get the coordinates of the bounding box for y:
        int countourMaximumY = contourRect.y + contourRect.height;
        if ( countourMaximumY > maxY ){
            maxY = countourMaximumY;
        }

        if ( contourRect.y < minY ){
            minY = contourRect.y;
        }
    }

}

At the end, you can get the final width and height of your "composite" bounding box like this:

//width and height of the composite box:  
int width = maxX - minX;
int height = maxY - minY;

The data of the final bounding box should be given by minX, minY, width and height.

stateMachine
  • 5,227
  • 4
  • 13
  • 29
2

thanks fmw42 for you proposition , i did implement the C++ code proposed by eldesgraciado and it's work , this is my implementation with python for who have the same issues in python :

label_image = measure.label(binary_car_image)

minY, minX, maxY, maxX = 5000, 5000, 0, 0

for region in regionprops(label_image):
    if region.area < 50:
        continue
    min_row, min_col, max_row, max_col = region.bbox
    region_height = max_row - min_row
    region_width = max_col - min_col
    countourMaximumY = max_row + region_height
    if countourMaximumY > maxY:
        maxY = countourMaximumY
    countourMaximumX = max_col + region_width
    if countourMaximumX > maxX:
        maxX = countourMaximumX
    if min_row < minY:
        minY = min_row
    if min_col < minX:
        minX = min_col

and use

min_row, min_col, max_row, max_col = minY, minX, maxY, maxX

instead of

min_row, min_col, max_row, max_col = region.bbox
MoxGeek
  • 458
  • 6
  • 17