How to identify smaller regions sandwiched between larger regions in watershed image?
- bwboundaries to find out the pixel indices of each region, use the pixel indices to find actual pixels and then compare the pixels for red regions and blue regions to find shared boundaries and thus, sort the red regions. The problem i faced here is that the bwboundaries command runs on the entire image containing the large and small regions alike, because of which it is impossible to understand which boundaries belong to the red regions and blue regions (probably not impossible but I could not think of any way here).
- Using knnsearch to identify the nearest 3 neighbors of a red region in the blue regions and then find if these neighbours share a boundary. The problem here, I guess, is that regionprops.PixelList does not record the boundary pixels of regions which renders the approach redundant.
5 Comments
- Get a mask for small blobs and large blobs separately.
- Dilate the large blobs two layers so it will overlap the small blobs.
- Determine the overlapping pixels.
- Use the overlapping pixels as markers with imreconstruct to get the small blobs that are next to the big blobs.
- AND the result with the original small blobs image to get only the small blobs that are next to large blobs (and not the merged blobs).
Answers (1)
Hi @Pranav,
To tackle the problem of identifying red regions that share boundaries with blue regions in a binarized watershed image, we can adopt a more systematic approach. The goal is to determine the shared boundaries and store the relevant properties of the red regions. Below is a detailed explanation of the steps involved, along with an updated code snippet.
First, utilize regionprops to obtain the centroids, pixel lists, and areas of the regions in the image. Then, seperate the regions based on their areas into two categories: red regions (areas < 100) and blue regions (areas >= 100). Use bwboundaries to extract the boundaries of the entire labeled image. For more information on bwboundaries function, please refer to:
https://www.mathworks.com/help/images/ref/bwboundaries.html
This will help in identifying the boundary pixels of both red and blue regions. For each red region, check if any of its boundary pixels coincide with the boundary pixels of any blue region. If a red region shares a boundary with a blue region, store its area, centroid, and pixel list in a structured format. Here is the revised version of your code that implements the above approach:
% Load a binary image binaryImage = imread('/MATLAB Drive/IMG_7682.PNG'); % Replace with your actual image file % Convert to binary if necessary binaryImage = imbinarize(rgb2gray(binaryImage)); % Convert to grayscale and then binary
% Create a labeled binary image Lb = bwlabel(binaryImage);
% Extract properties of the segmented regions props = regionprops(Lb, 'Centroid', 'PixelList', 'Area'); areas = cat(1, props.Area); centroids = cat(1, props.Centroid);
% Indices of large and small fiber regions idx_b = find(areas >= 100); idx_f = find(areas < 100);
% Sort the areas according to idx_f and idx_b area_f = areas(idx_f); area_b = areas(idx_b);
% Sort the Centroids according to idx_f and idx_b centroids_f = cell2mat({props(idx_f).Centroid}'); centroids_b = cell2mat({props(idx_b).Centroid}');
% Sort the PixelList according to idx_f and idx_b pixelList_f = {props(idx_f).PixelList}; pixelList_b = {props(idx_b).PixelList};
% Initialize a cell array to store the areas, centroids, and pixel lists of shared. regions sharedRegions = {};
% Loop through each red region for k = 1:length(pixelList_f) % Get the current red region's pixel list pixels_f = pixelList_f{k};
% Get the boundary of the current red region boundary_f = bwboundaries(reshape(ismember(Lb, idx_f(k)), size(Lb)), 'noholes'); boundary_f = boundary_f{1}; % Extract the first boundary
% Check against all blue regions for j = 1:length(pixelList_b) % Get the boundary of the current blue region boundary_b = bwboundaries(reshape(ismember(Lb, idx_b(j)), size(Lb)), 'noholes'); boundary_b = boundary_b{1}; % Extract the first boundary
% Check for shared boundary pixels sharedPixels = intersect(boundary_f, boundary_b, 'rows');
% If there are shared pixels, store the details if ~isempty(sharedPixels) sharedRegion = struct(); sharedRegion.Area = area_f(k); sharedRegion.Centroid = centroids_f(k, :); sharedRegion.PixelList = pixels_f; % Add the sharedRegion to the sharedRegions cell array sharedRegions{end+1} = sharedRegion; break; % Exit the loop once a shared boundary is found end end end
% Final plot to visualize the results figure; imshow(Lb, []); hold on;
% Plot red regions for k = 1:length(pixelList_f) if ismember(k, idx_f) plot(centroids_f(k, 1), centroids_f(k, 2), 'ro', 'MarkerSize', 10); end end
% Plot blue regions for j = 1:length(pixelList_b) if ismember(j, idx_b) plot(centroids_b(j, 1), centroids_b(j, 2), 'bo', 'MarkerSize', 10); end end
title('Centroids of Red and Blue Regions'); hold off;
Please see attached.
So, in your updated code, the bwboundaries function is used to extract the boundaries of both red and blue regions which allows to focus on the actual boundary pixels rather than the entire pixel list. The intersect function is employed to determine if there are any common pixels between the boundaries of the red and blue regions. If a shared boundary is found, the relevant properties of the red region are stored in a structured format for further analysis.
If you have any further questions or need additional assistance, feel free to ask!
4 Comments
Hi @Pranav,
After going through documentation for glcm documentation shared in the link below
https://www.mathworks.com/help/images/ref/graycomatrix.html
It seems that this approach will enrich your analysis by providing texture-based insights, the immediate issue of empty sharedRegions may be better resolved by refining the boundary detection methods or adjusting the segmentation thresholds. By incorporating visual validation and potentially dilating boundaries, you can enhance the accuracy of shared pixel identification. If you decide to proceed with GLCM, it will complement your existing methods by offering a deeper understanding of the textures present in your segmented regions.
See Also
Categories
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!