# Object differentiation in image

After purchasing a box of alphabet pasta for the kids, I wondered if there was way to extract the frequency of appearance of letters in the box by taken a sample and the analyzing the picture.

i = Import["http://i.imgur.com/qpFUSTo.jpg?1"];
a = Import["http://i.imgur.com/rHD21Gm.jpg"];
bwimg = Binarize@i; bwa = Binarize@a;
x = Table[
ImageCorrelate[bwimg, ImageRotate[bwa, i],
NormalizedSquaredEuclideanDistance], {i, 0, 141 Pi/72, Pi/72}];
y = Table[
Dilation[ColorNegate@Binarize[x[[i]], 0.07], DiskMatrix[50]], {i,
Length[x]}]; z =
HighlightColor -> Lighter@Green];
HighlightImage[i, z, HighlightColor -> Lighter@Green]


The result was less than promising, as a) it is time consuming, and b) several letters were missed by the process. I marked with Red and Orange arrows several letters that were missed.

Tried with the Binarize parameter (currently set at 0.07), but increasing it brought false positives into the mix.

Thought about MorphologicalComponents, which is very fast, and if the Colorize option can differentiate the objects, maybe it could be used to extract each letter, then maybe ImageAlign and group together. But that is beyond my skillset.

Any light on how to differentiate and tally the different letters would be appreciated.

-
You can greatly simplify the problem. (1) drastically overcook the pasta. (2) Spread as above. (3) They all look the same... but seriously, neat question & demo for the kids. –  rasher Feb 24 at 3:31

I won't deal with the speed factor yet, mainly with the pattern recognition. It is usually a lot easier to detect patterns using the edge patterns of an image, so you were in the right track with the morphological components.

Using the Schaar 3x3 operators we filter the image so that we can only see the edges:

myedges[v_] := ((ImageData@ImageConvolve[#, {{-3, -10, -3}, {0, 0, 0}, {3, 10, 3}}])^2 +
(ImageData@ImageConvolve[#, {{-3, 0, 3}, {-10, 0, 10}, {-3, 0, 3}}])^2)&@(Binarize@v);

bwimg = Image[myedges[i]]
bwa = Image[myedges[a]]


Where i and a are as given in the question.

Now instead of using bwa, I used bwa inverted left/right. It seemed to me that the side of some of the A's were a bit noisy, and the reserve seems to work better. You can try a combination of Letter and Reverse Letter to do the matching for other letters. (It also may be more natural since I suppose they are made from the same moulds and left/right symmetry may not be perfect in the moulding process) In this case we just use the reversed case:

bwat = ImageRotate[Image[Transpose@(myedges[a])], -Pi/2]


Using the same approach you did, now using the edge images, with the reversed A edge image:

x = Table[ImageCorrelate[bwimg, ImageRotate[bwat, i],
NormalizedSquaredEuclideanDistance], {i, 0., 141 Pi/72., Pi/72.}];

y = Map[Dilation[ColorNegate@Binarize[#, 0.26], DiskMatrix[30]] &,
x];