Search code examples
matlabimage-comparison

Irregular Shape Comparison between two inputs


I'm trying to come up with a scoring system for some behavioural psychology research.

I ask people to draw a letter, then trace over it, both on a graphics tablet. I want to assess the accuracy of this trace. So, you draw any letter ('a'), then you do it again, then I score it based on how similar it was to the first time you drew it. The drawings are stored as pixel locations.

Accuracy is assessed as closeness to the original letter. The method does not need to allow for scale, rotation or position changing. Conceptually it's like the area between the two lines, only the lines are highly irregular, so integrals (to my knowledge) wont work.

I'm writing in MATLAB, but any conceptual help would be appreciated. I've tried summing the minimum distance between all pixels drawn on, but this gives good (low) scores to well placed single points.

This must have been done before, but I'm not having any luck with my searches.

--- Partial Solution using method suggested by @Bill below. Doesn't work, as the bwdist gradient is too steep. Rather than the nice second image Bill shows, it looks more like the original.

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

Solution

  • What could help you is a distance transform, implemented in MATLAB as bwdist. This rewards lines being close, even if they don't match.

    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

    You can do the same with the second image, and sum up the difference in pixel values in the distance transformed images, something like:

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

    (Note that this will give higher scores to less similar images and v.v.)

    To help prevent issues that you mention of "good (low) scores to well placed single points", you could experiment with other distance measures, such as squared distance between pixel values.