5

私は次の問題を抱えています:

画像が表示され、ブロブ検出を行っています。制限として、最大16個のブロブがあり、各ブロブから重心(x、y位置)を計算するとします。歪みが発生しない場合、これらの重心は等距離の4x4グリッドに配置されますが、実際にはかなり歪んでいる可能性があります。それらは多かれ少なかれグリッド形式を維持しますが、実際にはかなり歪んでいる可能性があると想定されています。

左、右、上、下に最も近いものがわかるように、ブロブを並べ替える必要があります。したがって、これらのBLOBをマトリックスに書き込むのが最善です。

これが十分でない場合は、16未満を検出し、それらをマトリックスにソートする必要がある可能性があります。

これをMatlabで効率的に解決する方法を知っている人はいますか?

ありがとう。

[更新1:]

画像をアップロードしました。赤い数字は、ブロブ検出アルゴリズムが各ブロブに割り当てる番号です。

結果の行列は、次の数値で次のようになります。

1   2   4   3
6   5   7   8
9  10  11  12
13 16  14  15

たとえば、blob 11から始めて、最も近い正しい番号は12などです。

例

[更新2:]

投稿されたソリューションは非常に見栄えがします。実際には、外側のスポットの1つが欠落しているか、2つが欠落している可能性があります...これにより、すべてがはるかに複雑になることを知っています。これが時間を費やす価値があるかどうかを感じたいだけです。

これらの問題は、シャックハルトマン波面センサーを使用して波面を分析し、ダイナミックレンジを拡大したい場合に発生します:-)分割線が直交しなくなるように、スポットが実際に歪む可能性があります。

多分誰かが分類アルゴリズムのための良い文献を知っています。

最善の解決策は、それほど労力をかけずにFPGAに実装できるものですが、この段階ではそれほど重要ではありません。

4

1 に答える 1

1

これは、ブロブが正方形を形成し、比較的順序付けられている限り機能します。

画像:

ここに画像の説明を入力してください

コード:

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
于 2013-03-24T22:34:42.023 に答える