2012-02-06 17 views
5

私はいくつかの行動心理学の研究のためにスコアリングシステムを考え出しています。不規則な形状の比較

私は、人に手紙を描いてからグラフィックスタブレットの上を辿るように頼んでいます。私はこの痕跡の正確さを評価したいと思います。だから、あなたはどんな手紙( 'a')を描いても、それをやり直してから、それを初めて描いたときのそれに似ています。図面はピクセル位置として記憶される。

精度は元の手紙との類似度として評価されます。この方法では、スケール、回転または位置の変更が可能である必要はありません。概念的には、それは2つの線の間の領域のようであり、線のみが非常に不規則であるため、インテグラルは(私の知る限り)機能しません。

私はMATLABで書いていますが、概念的な助けをいただければ幸いです。私は描かれたすべてのピクセルの間の最小距離を合計しようとしましたが、これはよく配置された単一点に良い(低い)得点を与えます。

これは前に行われていたはずですが、私は検索に幸運を得ないです。どんな助けも大変ありがとう!

---下記の@Billで提案されている部分的な解決方法を使用します。 bwdistのグラデーションが急峻すぎるので、うまくいきません。 Billが見せてくれる素敵な第2のイメージではなく、元のイメージに似ています。あなたはbwdistとしてMATLABで実装distance transform、ある助けることができる何

%% Letter to image 
im = zeros(1080,1920,3); % The screen (possible pixel locations) 
% A small square a bit like the letter 'a', a couple of pixels wide. 
pixthick = 5; 
im(450:450+pixthick,[900:1100],:) = 1; 
im(550:550+pixthick,[900:1100],:) = 1; 
im([450:550],900:900+pixthick,:) = 1; 
im([450:570],1100:1100+pixthick,:) = 1; 
subplot(2,1,1); imagesc(im); %% atransbw = bwdist(im(:,:,1)<0.5); subplot(2,1,2); 
imagesc(atransbw); 
+0

既に説明した方法の問題点は何ですか? (最短距離の合計) – Ali

+0

最短距離を見つけるのに1つの値しかないため、1つのポイントの得点は非常に高くなります。例えば。円の中心に点を想像してください。最短距離の合計は小さく、良いスコアを意味します。実際には非常に悪い痕跡です。 – dgmp88

答えて

2

。たとえ一致しなくても、これは近くにある行に報酬を与えます。

a_img_1 = imread('a.jpg'); 
imagesc(a_img_1); 

enter image description here

a_img_1_dist_transform = bwdist(a(:, :, 1) < 250); 
imagesc(a_img_1_dist_transform); 

enter image description here

あなたは第二の画像と同じことを行うと、距離変換画像の画素値の差を合計することができ、何かのように:

score = sum(abs(a_img_1_dist_transform(:) - a_img_2_dist_transform(:))) 

(これにより、

"良い(低い)得点とよく配置された単一点"の問題を防ぐために、ピクセル値間の平方された距離などの他の距離測定を試すことができます。

+0

OK、これを試して実装します - ありがとう!このソリューションの私の唯一の問題は、 '画像'がベクトルとしてのみ格納されるため、非常に高価なことです。申し訳ありませんが、私はあまり明確ではないと思います。画像比較は最良のタグではないかもしれません。それでも、これはうまくいくかもしれません、私は会議の後すぐに試してみます。乾杯! (投票しようとしましたが、私の担当者はまだ高くありません) – dgmp88

+0

ラスタファイルではなくベクトル画像として保存されているのですか?その場合、はい、私は確かにこの答えよりも良い方法になります。 –

+0

イメージでもない - ペンがグラフィックタブレットに触れたピクセル位置の単なる2次元ベクトルです。 – dgmp88

1

エラー基準、たとえば平均二乗誤差と一致するアフィン変換が必要な場合があります。このようにして、翻訳とスケーリングを不変にします。また、翻訳のペナルティをかけたい場合は、翻訳コストも追加できます。 (どのような種類の機能が似ていると思われるかについてより多くの情報を提供すれば、助けになるでしょう)

今、効率的な実装は別の問題です。おそらく、あなたは画像登録に目を通すべきです。私はこれが何度も行われたと確信しています。

+0

翻訳とスケーリングに対する不変性は重要ではありません。概念的には、オリジナルとトレースの間の面積を計算するいくつかの方法は完璧です。ペイントでバケツの塗りつぶしツールを使用すると、オリジナルとトレースが逸れている場所ごとに、完璧に見えるようなものがあります。 私はアフィン変換と画像登録、歓声を調べます! – dgmp88

0

私は実際にはるかに高いレベルのソリューションを提案します。何らかの信頼を返すOCR機械学習アルゴリズムを見つける。または、自信がない場合は、出力テキストと実際のテキストとの距離をテストします。
これは手書きを見て、それを理解しようとする人間のようなものです。信頼度が高いほど、結果は良好です。

+0

OCRソリューションは本当に高いレベルのようです。私はそれが動作すると確信していますが、私は単純な解決策を望んでいます、私はちょうど文字を定義するためにピクセル位置のコレクションを使用しています。 はい、私は最後にこれをしなければならないかもしれません:)。 – dgmp88

3

シェイプコンテキストは、シェイプの「極点ヒストグラム」に基づく強力なフィーチャ記述子です。 Wikipedia pageは詳細ですが、hereは、追加情報(およびその技術の適切な視覚的説明)とMATLAB demo codeという別のページです。マッチングする文字は、このメソッドの元のアプリケーションの1つでした。私がリンクしているデモコードでは、トレースベクトルをイメージに変換する必要はありません。

もっと単純な方法は、2つの文字の排他的論理和として定義される「イメージの差」です。これには、トレースベクトルをバイナリイメージに変換する必要があります。ような何か:あなたのトレースのベクトルはポイント数が同じ、またはサンプリングによって行うことができる場合

x = xor(im1,im2); 
d = sum(x(:))/sum(im1(:)); %# normalize to the first image 

は最後に、プロクラステス分析に有用である可能性があります。 Procrustes解析の考え方は、2組の点の間で最小二乗最適線形変換(回転、平行移動、スケーリング)を見つけることです。 2つの点集合間の適合度は、「Procrustes統計量」または点の平方根二乗偏差のような他の尺度によって与えられる。

%# Whatever makes sense; 
%# procrustes needs N x 2 matrices with (x,y) coords for N points. 
coords1 = [x1 y1]; 
coords2 = [x2 y2]; 

%# This sampling may be too naive. 
n = max(size(coords1,1), size(coords2,1)); 
coords1 = coords1(1:n,:); 
coords2 = coords2(1:n,:); 

%# d is sum-of-squares error 
%# z is transformed coords2 
%# tr is the linear transformation 
[ d, z, tr ] = procrustes(coords1, coords2); 

%# RMS deviation of points may be better than SSE. 
n = size(coords1,1); 
rmsd = sqrt((sum((coords1(:) - z(:)).^2)/n)); 
+0

良いアイデア、ありがとう!しかし、1つの問題は、私は、文脈に依存して形作るさまざまな変換に不変性を望んでいないということです。 – dgmp88

+0

'procrustes(X、Y、 'scaling'、false)'を使ってスケーリングコンポーネントをオフにすることができます。また、ポイントのRMSDまたはSSEを直接使用することもできます。 –

+0

ありがとうございます。私はそれをテストし、Bill Cheathamが提案した別のバージョンのソリューションと比較します。 – dgmp88

1

これは基本的にBill Cheathamの方法を使用する、私の最後の複雑すぎる解決方法です。すべての助けをありがとう!

% pixLet is the 2D vector contain locations where drawing occurred. First convert it to an image. 

im = zeros(1000,1000); % This is the image 
for pix = 2:size(pixLet,1) 
    y1 = pixLet(pix-1,2); x1 = pixLet(pix-1,1); 
    y2 = pixLet(pix,2); x2 = pixLet(pix,1); 
    xyd = round(pdist([x1 y1; x2 y2])*2); 
    xs = round(linspace(x1,x2,xyd)); 
    ys = round(linspace(y1,y2,xyd)); 
    for linepix = 1:length(xs) 
     im(ys(linepix),xs(linepix)) = 1; 
    end 
end 

% Blur the image 
blur = fspecial('gaussian',[sz sz],reach); 
gausIm = conv2(im,blur,'same'); 

% I made a function of the above to do this for both the template and the trace. 
score = sum(sum(abs(gausIm1-gausIm2))); 
関連する問題