Extracting spot coordinates from an given line in an image for an almost regular hex pattern of spots but when there is a slight tilt on Y coordinate values.
7 次查看(过去 30 天)
显示 更早的评论
Hello, I have greyscale image that I am trying to get the positons of the centroids within a given row (i.e the red line below)

The problem is that there is a slight "twist" in my image meaning the y-centroids for a given row actually drift as can be seen below.

The solid CYAN line is a horizontal line which passes thru' the centroid of the most central spot, and you can see at the extreme right and left, the required spots are above or below this line due to the "image twist". But I need to extract the centroids of all the objects on this (tilted) line. The green dashed lines are the centre of the image

This is the most central part, and its easy to extract the centroids of all the objects. The most centralised spot has cooridinates xc,yc (magenta circle). All my other centroids are in vectors x1,y1
But as I only need the centroids on the red line, I filter out all spots above a y-value threshold of say 6 pixels above or below (cyan dashed lines) as I don't want and spots from the row above or below
But its inevitable at the extremes, the spots i want are above or below this threshold and thus not being considered, but instead the spots from one of these upper or lower rows now are counted which I don't want
Im not sure how to proceed, this is my code so far:
ax=app.UIAxes2; IM=getimage(ax); % My function to get the image from the axes [sy,sx]=size(IM); yc=round(sy/2); xc=round(sx/2); % Centre of Image
% Get centroids that have already been found
x1=app.x1; y1=app.y1; % Get saved centroids
% Find most central ones in y, need ROI dimensions
yline(ax,yc,'g--');
xline(ax,xc,'g--');
%Get distance of all x,y's from centre (yc)
n=numel(x1);
data=[];
for i=1:n
dabs = abs(y1(i)-yc); % Y distance of each spot from centre y value
%Below gets the most central spot coordinate
X = [x1(i),y1(i);xc,yc];
dcen = pdist(X,'euclidean');
data(i,1)=i; data(i,2)=x1(i); data(i,3)=y1(i); data(i,4)=dabs; data(i,6)=dcen;
% get intensity at each x,y location (so can remove
% lowest as spurious spots if required
Intensity=IM(round(y1(i)),round(x1(i)));
data(i,5)=Intensity;
end
% Find spot nearest to centre of image (xc,yc)
A = sortrows(data , 6,'ascend'); % sort on distance to centre of image
hold (ax,"on");
XX=A(1,2); YY=A(1,3); % ******* Most Spot Central coordinate ******
yline(ax,YY,'c');
plot(ax,XX,YY,'mo','MarkerSize',20);
disp('distance from cen, all spots')
% This is where I remove all spots with a y value above a distance
% from the most centralised spot
% Remove all rows with y diffences above a ythresh, say 6 pixels
% Effectively ignore all spots except on central line
ythresh=6;
A(A(:,4) > ythresh, :)=[];
plot(ax,A(:,2),A(:,3),'r+','MarkerSize',20);
yline(ax,yc+ythresh,'c--'); yline(ax,yc-ythresh,'c--'); % Show lines constraints on y coordinate
%Remove Spurious spots, i.e. any low intensity ones if any;
Icol=A(:,5); % Get intensity Column
med1=median(Icol); % get median of this column
thr=med1*0.3; % define a threshold (0.3) of median value to remove
A(A(:,5) < thr, :)=[]; % Remove weak spots
A= sortrows(A , 5,"ascend");
% MY AIM IS TO HAVE A VECTOR OF X VALUES OF THE RELEVANT SPOTS ALL
% REFERENCE TO THE MOST CENTRAL SPOT.
% Extract X coords and extract off 1st (=central location spot) X value
% so all relative to centralised spot
C = sortrows(A , 6,'ascend'); % sort on dcen
xvalues=C(:,2);
disp('Central Spot X')
XX
xvalueCen=C(1,2)
xref=xvalues-xvalueCen;
%This is where Im running into difficulty as Im picking up the
%spot centroids from the wrong row due to the tilt
1 个评论
采纳的回答
Mathieu NOE
2025-7-10
hello again
maybe you could implement this method :
%% create some dummy pattern of centroids
% center of image (central spot coordinates) is 0,0
xc = 0;
yc = 0;
N = 10;
dx = 1;
x = -N:dx:N;
for k=1:7
y = (k-4)*ones(size(x)) - 0.5*(k)*(cos(pi*x/N)-1);
y_all(k,:) = y; % storage
end
%% selection based on threshold (as you did) - it will fail
threshold = 0.5;
ydist = abs(y_all - yc);
ind = (ydist<threshold);
x_select = x(any(ind,1));
y_select = y_all(ind);
figure
hold on
plot(x,y_all,'*')
plot(x_select,y_select,'dk','markersize',15)
hold off
%% "smart" selection based on closest neighbour search
nx = numel(x);
threshold = 0.5;
indxc = find(x==xc);
% init
y_select2 = zeros(1,nx);
x_select2(indxc) = xc;
y_select2(indxc) = yc;
% right half closest neighbour search (for x > xc)
for ii=indxc+1:nx
ydist = abs(y_all(:,ii) - y_select2(ii-1));
[val,ind] = min(ydist);
y_select2(ii) = y_all(ind,ii);
end
% left half closest neighbour search (for x < xc)
for ii=indxc-1:-1:1
ydist = abs(y_all(:,ii) - y_select2(ii+1));
[val,ind] = min(ydist);
y_select2(ii) = y_all(ind,ii);
end
figure
hold on
plot(x,y_all,'*')
plot(x,y_select2,'dk','markersize',15)
hold off
15 个评论
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!