Detecting centre of multiple concentric small circles/ellipses

조회 수: 15 (최근 30일)
PG
PG 2022년 11월 26일
댓글: PG 2022년 12월 8일
Hi everyone, I have an image (.txt file format) that has a series of almost concentric and nearly circular/ellipsoidal shapes/patterns. These circles/ellipses are very small compared to the overall image size. Please find attached: 1) Original .txt file, 2) Two screenshots, one of the overall image and one of the zoomed in version, 3) Code that loads the image and generates the two screenshots.
My goal is to find what is the pixel in the original .txt that is the centre of these circles/ellipses with good accuracy and repeatability.
I tried to use both the functions "imfindcircles" with a large radius range and "ellipseDetection" (developed by Martin Simonovsky, see link below) but I was not successful in implementing them/achieving the required result.
Is anyone able to help please?
Ellipse Detection Using 1D Hough Transform; Martin Simonovsky -> https://ch.mathworks.com/matlabcentral/fileexchange/33970-ellipse-detection-using-1d-hough-transform
  댓글 수: 2
Matt J
Matt J 2022년 11월 28일
The ellipses in the image do not look perfectly concentric. Are they supposed to be?
PG
PG 2022년 11월 28일
Hi Matt, Thanks for your question. In theory they should be, in practice they are not. I am mostly interested about the centre of the smallest circle/ellipse, but since it has different diameters in different images I thought about finding the centre of circles/diameters with a certain radii range and then average the position of the centre

댓글을 달려면 로그인하십시오.

답변 (2개)

Image Analyst
Image Analyst 2022년 11월 26일
It's probably at the weighted centroid of the whole image so I'd just use regionprops.
mask = true(size(fullImage));
props = regionprops(mask, fullImage, 'WeightedCentroid');
xCentroid = props.WeightedCentroid(1);
yCentroid = props.WeightedCentroid(2);
  댓글 수: 3
Image Analyst
Image Analyst 2022년 11월 27일
I'm working on something that I'll continue and post tomorrow.
PG
PG 2022년 11월 28일
Thank you very much, I am looking forward to it!

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2022년 11월 28일
Try this:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
y_in=880;
y_fin=1080;
x_in=690;
x_fin=790;
imageData=load('ImageFile_0.txt');
[rows, columns] = size(imageData)
subplot(2, 2, 1);
% There are bad, spurious pixel values in the last row so set that row to zero.
imageData(end, :) = 0;
imshow(imageData, [], 'ColorMap', turbo);
impixelinfo;
axis('on', 'image')
colorbar;
clim([0, 50]);
subplot(2, 2, 2);
[counts, edges] = histcounts(imageData);
% Set counts for 0, and 2 gray levels to 0 so we can see bars for the other values.
counts(1:3) = 0;
bar(edges(1:end-1), counts);
grid on;
xlim([0, 100]);
drawnow;
% Find the blob.
mask = bwareafilt(imageData >= 3, 1);
mask = imfill(mask, 'holes');
% Erode the mask a lot.
% se = strel('disk', 200, 6);
% mask = imerode(mask, se);
subplot(2, 2, 3);
imshow(mask);
% Crop it.
props = regionprops(mask, 'BoundingBox', 'Centroid');
% Plot centroid over original image.
subplot(2, 2, 1);
hold on;
plot(props.Centroid(1), props.Centroid(2), 'r+', 'MarkerSize', 50);
drawnow;
% Create a logical image of a circle with specified
% diameter, center, and image size.
% First create the image.
imageSizeX = columns;
imageSizeY = rows;
[columnsInImage rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY);
% Next create the circle in the image.
centerX = props.Centroid(1);
centerY = props.Centroid(2);
radius = 300;
circlePixels = (rowsInImage - centerY).^2 ...
+ (columnsInImage - centerX).^2 <= radius.^2;
% circlePixels is a 2D "logical" array.
% Now, display it.
subplot(2, 2, 3);
imshow(circlePixels);
title('Circular mask around centroid', 'FontSize', fontSize);
% Find the bounding box so we can crop it.
props = regionprops(circlePixels, 'BoundingBox', 'Centroid');
% Crop out the main part so we can see it bigger.
subImage = imcrop(imageData, props.BoundingBox);
subplot(2, 2, 4);
% subImage = imageData((y_in:y_fin),(x_in:x_fin));
imshow(subImage, []);
axis('on', 'image')
impixelinfo
colorbar;
colormap('gray')
% Find the brightest pixel
maxGL = max(subImage(:))
[r, c] = find(subImage == maxGL)
xBrightest = c(1);
yBrightest = r(1);
hold on;
plot(xBrightest, yBrightest, 'g+', 'MarkerSize', 50, 'LineWidth', 2);
drawnow;
caption = sprintf('Brightest pixel at (x,y) = (%.3f, %.3f) with value %d', xBrightest, yBrightest, maxGL)
title(caption, 'FontSize', fontSize);
  댓글 수: 4
Image Analyst
Image Analyst 2022년 11월 30일
Have you tried imfindcircles()? Try that.
PG
PG 2022년 12월 8일
Hi, thanks for your reply!
Replying to the 1st comment: Maybe my question was not clear enough because I am not looking to find the brightest point of the image. This could be simply achieved by finding the coordinates of the maximum intensity point in the whole image (that is what you do in your two lines:
maxGL = max(subImage(:))
[r, c] = find(subImage == maxGL)
My goal is to find what is the pixel that is the centre of these circles/ellipses with good accuracy and repeatability. As you can see from the two figures I provided, the intensity profile in one of them (ImageFile_0.txt) is such that the brigtest spot is at the centre of the circle/ellipse while in the other image (ImageFile_100.txt) the brigtest pixel is on the edge of the donut shape. That is why the "max intensity" is not a general enough criteria for me.
I tried to use the following criteria with WeightedCentroid:
ImageFile=load(['ImageFile_100.txt']);
ImageFile=ImageFile((y_in:y_fin),(x_in:x_fin));
I_Max=max(max(ImageFile));
threshold1=0.7 * I_Max;
ImageFile(ImageFile<=threshold1)=0; % To remove the noise
ImageFile(ImageFile>threshold1)=1; % To not give excessive weight to the highest pixels intensity
ROI = true(size(ImageFile));
props = regionprops(ROI, ImageFile, 'WeightedCentroid');
xWCentroid = props.WeightedCentroid(1);
yWCentroid = props.WeightedCentroid(2);
However in certain instances the circles/ellipses even though they have a quite definite shape, the pixels distribution is not symmetric and the weighted centroid does not return the geometrical centre. Hence why I would still like to fins a way (like imfindcircles()) that allows me to inscribe these regions in circles/ellipses and compute the geometrical centre.
Replying to 2nd comment: Yes, I did try "imfindcircles()" as I mentioned in the original question, however, for some reason, no matter how I changed the different parameters, it was not working with the images I had. I do not know if this might be due to the fact my circles are too small maybe.
Any suggestion would be highly appreciated!

댓글을 달려면 로그인하십시오.

제품


릴리스

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by