Hi, In order to continue processing data for the experiment results, I have to calculate the spray penetration length based on the spray image. Previously I got the code from Image Analyst to calculate the spray cone angle as a reference. My current idea is to set the spray plume segmentation from the binary image first in order to define the spray boundary, then start to measure the along the Y axis from spray origin to the farthest point of the spray (Please refer to the attach. 1 images) How I can proceed after getting the initial binary image? I tried to use bwboundaries function but didn't manage to get it right. Then, if the spray plume segmentation is fully defined, can the spray area be calculated also? It would be very very helpful if these two cases can be solved. Please kindly guide me to resolve this problem. The image that will be processed is also attached I changed the radius but I am not sure which one to delete, could you give advice? function grayImage = CircleMaskImage(grayImage) % Get the size of the image. [imageSizeY, imageSizeX, numberOfColorChannels] = size(grayImage); % Create a logical image of a circle with specified % diameter, center, and image size. % First create the image. [columnsInImage, rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY); % Next create the circle in the image. centerX = imageSizeX / 2; centerY = imageSizeY / 2; radius = 170; % Display circle in the overlay above the current axes. viscircles([centerX, centerY], radius, 'Color', 'r'); % Here is where we actually create the mask. circlePixels = (rowsInImage - centerY).^2 ... + (columnsInImage - centerX).^2 <= radius.^2; % circlePixels is a 2D "logical" array. % Now, display it. % image(circlePixels) ; % colormap([0 0 0; 1 1 1]); % title('Binary image of a circle'); % Set image outside the circle to some very bright value % so it won't be selected when we do a threshold for dark stuff. grayImage(~circlePixels) = 65535; end
Kshitij Singh answered .
2025-11-20
There are several ways you can determine the starting and ending rows. I think the fastest is just this
[blobRows, blobColumns] = find(binaryImage); topRow = min(blobRows) bottomRow = max(blobRows)
You could also use regionprops and ask for the bounding box.
props = regionprops(binaryImage, 'BoundingBox'); topRow = props.BoundingBox(2) + 0.5 bottomRow = topRow + props.BoundingBox(4) - 1
Row 41 looks like it should do it to erase the nozzle:
% Do an closing to smooth out the edges.
se = strel('disk', 3, 0);
binaryImage = imclose(binaryImage, se);
%---------------------------------------------------------------------------
% Fill any holes that might be present
binaryImage = imfill(binaryImage, 'holes');
% Erase nozzle.
binaryImage(1:41, :) = false;
%---------------------------------------------------------------------------
% Extract the blob with the largest area.
numberToExtract = 1;
binaryImage = bwareafilt(binaryImage, numberToExtract);
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage);
axis on;
title('Biggest Blob, Final Mask', 'FontSize', fontSize);
drawnow;