我有以下问题:
给出了图像,我正在进行一些斑点检测。作为限制,假设我有最多16个斑点,并且从每个斑点我计算质心(x,y位置)。 如果没有发生失真,这些质心排列在等距的4x4网格中,但它们可能会非常扭曲。 假设它们或多或少保持网格形式,但它们可能真的扭曲了。
我需要对blob进行排序,以便知道哪一个是最近的左,右,上和下。所以最好将这些blob写入矩阵。
如果这还不够,可能会发现我检测到的不到16,然后我还需要将它们排序成矩阵。
有谁知道如何在Matlab中有效地解决这个问题?
感谢。
[更新1:]
我上传了一张图片,红色数字是我的blob检测算法为每个blob分配的数字。
结果矩阵应如下所示:
1 2 4 3
6 5 7 8
9 10 11 12
13 16 14 15
e.g。我从blob 11开始,最近的正确数字是12,依此类推
[更新2:]
发布的解决方案看起来很不错。实际上它可能会发生,其中一个外部位置缺失或者可能是两个......我知道这会使一切变得更加复杂,我只是想感受一下这是否值得花时间。
如果您使用shack-hartmann波前传感器分析波前并且想要增加动态范围,则会出现这些问题:-) 这些斑点可能会被扭曲,使得分界线不再正交。
也许有人知道分类算法的好文献。
最佳解决方案是一个,可以在FPGA上实现,而不需要太多努力,但现阶段并不是那么重要。
答案 0 :(得分:1)
只要blob形成一个正方形并且相对有序,这将起作用:
图像:
代码:
bw = imread('blob.jpg');
bw = im2bw(bw);
rp = regionprops(bw,'Centroid');
% Must be a square
side = sqrt(length(rp));
centroids = vertcat(rp.Centroid);
centroid_labels = cellstr(num2str([1:length(rp)]'));
figure(1);
imshow(bw);
hold on;
text(centroids(:,1),centroids(:,2),centroid_labels,'Color','r','FontSize',60);
hold off;
% Find topleft element - minimum distance from origin
[~,topleft_idx] = min(sqrt(centroids(:,1).^2+centroids(:,2).^2));
% Find bottomright element - maximum distance from origin
[~,bottomright_idx] = max(sqrt(centroids(:,1).^2+centroids(:,2).^2));
% Find bottom left element - maximum normal distance from line formed by
% topleft and bottom right blob
A = centroids(bottomright_idx,2)-centroids(topleft_idx,2);
B = centroids(topleft_idx,1)-centroids(bottomright_idx,1);
C = -B*centroids(topleft_idx,2)-A*centroids(topleft_idx,1);
[~,bottomleft_idx] = max(abs(A*centroids(:,1)+B*centroids(:,2)+C)/sqrt(A^2+B^2));
% Sort blobs based on distance from line formed by topleft and bottomleft
% blob
A = centroids(bottomleft_idx,2)-centroids(topleft_idx,2);
B = centroids(topleft_idx,1)-centroids(bottomleft_idx,1);
C = -B*centroids(topleft_idx,2)-A*centroids(topleft_idx,1);
[~,leftsort_idx] = sort(abs(A*centroids(:,1)+B*centroids(:,2)+C)/sqrt(A^2+B^2));
% Reorder centroids and redetermine bottomright_idx and bottomleft_idx
centroids = centroids(leftsort_idx,:);
bottomright_idx = find(leftsort_idx == bottomright_idx);
bottomleft_idx = find(leftsort_idx == bottomleft_idx);
% Sort blobs based on distance from line formed by bottomleft and
% bottomright blob
A = centroids(bottomright_idx,2)-centroids(bottomleft_idx,2);
B = centroids(bottomleft_idx,1)-centroids(bottomright_idx,1);
C = -B*centroids(bottomleft_idx,2)-A*centroids(bottomleft_idx,1);
[~,bottomsort_idx] = sort(abs(A*reshape(centroids(:,1),side,side)+B*reshape(centroids(:,2),side,side)+C)/sqrt(A^2+B^2),'descend');
disp(leftsort_idx(bsxfun(@plus,bottomsort_idx,0:side:side^2-1)));
输出:
2 12 13 20 25 31
4 11 15 19 26 32
1 7 14 21 27 33
3 8 16 22 28 34
6 9 17 24 29 35
5 10 18 23 30 36
好奇,您是否正在使用它通过棋盘或其他东西自动进行相机校准?
更新: 对于倾斜的图像
tform = maketform('affine',[1 0 0; .5 1 0; 0 0 1]);
bw = imtransform(bw,tform);
输出:
1 4 8 16 21 25
2 5 10 18 23 26
3 6 13 19 27 29
7 9 17 24 30 32
11 14 20 28 33 35
12 15 22 31 34 36
对于旋转图像:
bw = imrotate(bw,20);
输出:
1 4 10 17 22 25
2 5 12 18 24 28
3 6 14 21 26 31
7 9 16 23 30 32
8 13 19 27 33 35
11 15 20 29 34 36