4

我正在尝试为一些行为心理学研究提出一个评分系统。

我要求人们在绘图板上画一个字母,然后在它上面描摹。我想评估此跟踪的准确性。所以,你画任何一个字母('a'),然后你再画一次,然后我根据它与你第一次画它的相似程度来给它打分。绘图存储为像素位置。

准确性被评估为与原始字母的接近程度。该方法不需要允许缩放、旋转或位置改变。从概念上讲,它就像两条线之间的区域,只有两条线是高度不规则的,所以积分(据我所知)不起作用。

我正在用 MATLAB 写作,但我们将不胜感激任何概念上的帮助。我尝试将绘制的所有像素之间的最小距离相加,但这会为放置良好的单点提供良好的(低)分数。

这一定是以前做过的,但我的搜索没有任何运气。

--- 使用下面@Bill 建议的方法的部分解决方案。不起作用,因为 bwdist 梯度太陡了。而不是比尔展示的漂亮的第二张图片,它看起来更像原版。

%% 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);
4

5 回答 5

3

形状上下文是一个强大的特征描述符,它基于形状的“极坐标直方图”。Wikipedia 页面很深入,但这里是另一个页面,其中包含附加信息(以及对该技术的良好可视化解释),以及MATLAB 演示代码。匹配字母是该方法的原始应用之一,我链接到的演示代码不需要您将跟踪向量转换为图像。

更简单的方法可能是将“图像差异”定义为两个字母的异或。这需要将您的跟踪向量转换为二进制图像。就像是:

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

最后,如果您的跟踪向量具有相同数量的点,或者可以通过抽样得到,Procrustes 分析可能会很有用。Procrustes 分析的思想是在两组点之间找到最小二乘最优线性变换(旋转、平移和缩放)。两个点集之间的拟合优度由“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));
于 2012-02-06T22:55:35.457 回答
2

可以帮助您的是距离变换,在 MATLAB 中实现为bwdist. 这奖励线接近,即使它们不匹配。

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

在此处输入图像描述

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

在此处输入图像描述

您可以对第二张图像执行相同的操作,并总结距离变换图像中像素值的差异,例如:

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

(请注意,这将为不太相似的图像和 vv 提供更高的分数)

为了帮助防止您提到“良好(低)分数到良好放置的单点”的问题,您可以尝试其他距离度量,例如像素值之间的平方距离。

于 2012-02-06T15:34:26.153 回答
1

您可能希望找到与某些误差标准匹配的仿射变换,例如均方误差。这样,您将不受平移和缩放的影响。或者如果你想惩罚翻译,你也可以增加翻译成本。(如果您提供更多关于哪些功能认为相似或其他方面的更多信息,这将有助于我们为您提供帮助)

现在,有效的实施是另一回事。也许您应该研究图像配准。我敢肯定这已经做过很多次了。

于 2012-02-06T16:13:35.430 回答
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)));
于 2012-02-09T14:00:08.170 回答
0

我实际上会建议一个更高级别的解决方案。找到一种能够返回某种置信度的 OCR 机器学习算法。或者,如果您没有信心,请测试输出文本与实际文本之间的距离。
这就像一个人看着笔迹并试图理解它。置信度越高,结果越好。

于 2012-02-06T16:21:38.473 回答