3

スタックオーバーフローのユーザーの皆様、

数年前、私は数ヶ月間数学を使いました。数年間プログラミングをしなかった後、私は学生として、Matlabを使用する研究プロジェクトを行っています。私はここでstackoverflowに関して多くの良い助けを見つけました、しかし今私は次の問題で立ち往生しています:

長方形グリッド上のノード間の接続のデータセットがあります。各ノードには、8つの隣接ノードへの接続があります。私の測定値は3行n列の行列の形式で、最初の2つの値はノードを示し、3番目の値はそれらが接続されているかどうかを示します。グリッドのサイズは事前に決定されています。通常、互いに少なくとも1つ隣接している2つまたは3つのノードからの約10本の線があります。私の研究プロジェクトの目標は、この線の集まりの周りの距離rの面積を計算することです。

これまでのところ、以下のコードで行をプロットすることができました。ここからスタックオーバーフローでコードのビットを使用しました。これは非常に便利でした。ただし、特定の距離でその周りの等高線を取得できません(この等高線の内側の面積を計算したいと思います)。gplot関数は、1行に2つの座標を持つ2つのベクトルを返しますが、これをより使いやすいものに変換するのは難しいと思います。線からの距離とともに値Zを定義して、線からの距離とともに減少するようにしたので、これらの線から傾斜が得られます。この勾配から等高線を計算できます。ただし、線は単なる座標であるため、関数である場合とは対照的に、その線までの距離を計算する方法がわかりません。

私は本当に途方に暮れています。私はここに私の問題をいくらか明確に投稿したことを望みます。この問題を投稿するのはこれが2回目ですが、コードと写真にコメントを追加して、自分自身をよりよく説明できるようにしました。アドバイスをありがとう!

これまでのところ、xlsファイルは上記の3行n列の行列です。また、以下のコードでその内容を行列形式で記述しているため、問題を理解しやすくなっています。

%# here i set my data/constants

filename='random.xls'; file=xlsread(filename); y=width; x=length; 

%# random.xls looks approximately like this, after xlsread(filename) you get

file=[21    22  1;
21  20  1;
15  16  1;
15  14  1;
15  23  1;
14  22  1;
14  21  1;
22  15  1;
23  14  1;
24  15  1;
6   15  1;
5   14  1;
7   14  1;
8   15  1];

%# predefined width and length, i usually get this from the file

width=8; length=4;

%# here i create my adjaceny matrix in a elegant way user amro posted on stackoverflow
%# however i immediately multiply it by 0, creating a y*x by y*x matrix with all zeroes

[X Y] = meshgrid(1:x,1:y); X = X(:); Y = Y(:); 
adjacency = squareform( pdist([X Y], 'chebychev') == 1 ); adjacency=adjacency*0;

%# here i take the matrix "file" for which the first two values are node numbers and 
%# the third value designates whether there is a connection between the two nodes to
%# fill in the connections in the adjacencymatrix

[nrows,ncols]=size(file);
for r = 1:nrows
      if file(r,3)==1
         adjacency(file(r,1),file(r,2))=1;
      end
end
adjacency=(adjacency+adjacency.');

%# plots the adjacencymatrix

subplot(121), spy(adjacency)

%# plots the connections and designates the nodes, note that the numbers designating
%# the nodes do not match original data, this is a separate problem i have not solved

[xx yy] = gplot(adjacency, [X Y]);
subplot(122), plot(xx, yy, 'ks-', 'MarkerFaceColor','b')

%# these last lines of code for plotting the numbers of the grid i do not fully
%# understand, in here is the cause for the numbers not matching the original data

axis([0 x+1 0 y+1])
[X Y] = meshgrid(1:x,1:y);
X = reshape(X',[],1) + 0.1; Y = reshape(Y',[],1) + 0.1;
text(X, Y(end:-1:1), cellstr(num2str((1:x*y)')) )
xlabel('length')
ylabel('width')
title(filename)

私の問題を明確にするために、私はこれらの2つの写真を追加しました:現在のプロットhttp://imgur.com/5uPd4 私が知りたいエリアhttp://imgur.com/WsIbg

4

1 に答える 1

1

Matlabの線のコレクションから距離rで等高線または等高線の内側の表面積を見つけるための解決策、正確または効率的なオーンサーではなく、グラフィカル処理(拡張)による近似!

私は概算を行ったので、これは正確なオーンサーではなく、効率的なコーディングでもありません。マシンビジョンを研究している私の友人は、線をピクセルに変換し、次にディスクで画像を拡張することを提案しました。その後、ピクセル数は表面積の尺度になります。

%# constants and variables
minx = min(xx);
miny = min(yy);
maxx = max(xx);
maxy = max(yy);
rangex = maxx - minx;
rangey = maxy - miny;
borderRelNum = sqrt(2);
electrodeToImageScaleFactor = 100;
imsizex = 2*(maxx+borderRelNum)*electrodeToImageScaleFactor+2;
imsizey = 2*(maxy+borderRelNum)*electrodeToImageScaleFactor+2;
im = zeros(imsizex, imsizey);
grayscalevalue = 255;
disksize = round(borderRelNum*electrodeToImageScaleFactor);

%# transformation matrices
centerElectrodeSpace = [1, 0, -(minx + maxx) / 2;
                0, 1, -(miny + maxy) / 2;
                0, 0, 1 ];

scaleElectrodeToImage = [electrodeToImageScaleFactor , 0, 0;
             0, electrodeToImageScaleFactor , 0;
             0, 0, 1 ];

centerImageSpace = [ 1, 0, imsizex / 2;
             0, 1, imsizey / 2;
             0, 0, 1 ];

electrodeToImage = centerImageSpace * scaleElectrodeToImage * centerElectrodeSpace;

%# transformation

for i = 0:(size(xx,1) / 3 - 1) 
    p1 = [xx(i*3 + 1); yy(i*3 + 1); 1];
    p2 = [xx(i*3 + 2); yy(i*3 + 2); 1];     

    p1im = electrodeToImage * p1
    p2im = electrodeToImage * p2

    lx = linspace( min( p1im(1), p2im(1) ), max( p1im(1), p2im(1) ), borderRelNum*electrodeToImageScaleFactor )
    ly = linspace( min( p1im(2), p2im(2) ), max( p1im(2), p2im(2) ), borderRelNum*electrodeToImageScaleFactor )

    index = sub2ind(size(im),round(lx),round(ly));
    im(index) = grayscalevalue;     
end

%# Now dilate and count pixels
    se = strel('disk', disksize, 0);
im = imdilate(im, se);
image(im)
    colormap(gray)
    sum(sum(im/grayscalevalue))*(1/electrodeToImageScaleFactor^2)

誰かが私の問題をよりエレガントに、効率的に、またはより正確に解決することができれば、それでも私はそれを非常に高く評価します。しかし、これは今のところうまくいくでしょう。

-編集-わかりました、これは確かに非常に非効率的です。私のPCはデータセット(10 xlsファイル、それほど多くはありません)で30分間数値を処理していて、まだファイル1にあります。ワークスペースの値を見ると、

于 2012-08-27T22:32:24.883 に答える