Search code examples
matlabimage-processingimage-segmentationthreshold

Image segmentation with region-based thresholds in Matlab


I have a noisy image with multiple separated circular regions that are blurred out. An example of such image with six Region of Interests (ROI) is :

enter image description here image source

Segmenting this image with global threshold is easy in Matlab using bwconncomp and a given threshold. But I want to set a fix threshold (e.g. 54%) with respect to the maximum pixel value of every ROI (instead of the whole image) to segment each ROI.

I have a collection of images with different ROI sizes and positions, and I need to segment them all based on the regional-based thresholding, therefore I cannot use Matlab interactive tool to select them either.

Thanks


Solution

  • After you've done connected component analysis try using bwlabel. It will label each of your 6 regions a number 1-6. Then you use each of the regions/labels as a mask. You look at only the values in the region and find your max

    %after bwconncomp
    lbls = bwlabel(my_bw_conn_output);
    num_lbls = max(lbls(:));
    
    percentage_of_max = 54;
    my_thresh = zeros(1,num_lbls);
    
    for ii=1:num_lbls
        %isolates only one ROI
        temp_mask = (lbls == ii);
    
        %we do two maxes, one for rows one for columns
        max_val = max(max(uint8(temp_mask) .* image_with_values_to_threshold));
    
        %this could be for color pictures too
        my_thresh(ii) = percentage_of_max * max_val
    end
    

    edit

    If you want to use the results of your bwconncomp directly do something more like this

    %my code is written assuming you started with a grayscale image, though you
    %could adapt it for a color image
    cc = bwconncomp(grayscale_image);
    percentage_of_max = 54;
    
    for ii=1:cc.NumObjects
        mask = zeros(cc.ImageSize);
    
        %converts the indexes back to x,y coordinates
        [x_coords,y_coords] = ind2sub(cc.ImageSize,cc.PixelIdxList{ii}(:));
        mask(x_coords,y_coords) = 1;
    
        %masks the image
        roi_im = bsxfun(@times, uint8(mask), grayscale_image);
    
        %% do processing for this region here using roi_im 
        curr_thresh = max(roi_im (:)) * percentage_of_max;
    
        thesh_im = grayscale_image > curr_thresh;
    end
    

    another alternative is to crop the images and then to simply run your calculations on the cropped image. I jsut came across this SO post How to crop face section from an image with given corner points. MATLAB that helps with cropping perfect squares. You can also use roipoly if you have another shape that isn't a rectangle.