Detecting centre of multiple concentric small circles/ellipses

11 ビュー (過去 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 件のコメント
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 件のコメント
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 件のコメント
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!

サインインしてコメントする。

カテゴリ

Find more on Convert Image Type in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by