A year late, but here are my thoughts:
As Szabolcs showed, extracting the Line primitives from a RegionPlot provides a convenient way to produce a polygon from an image. The function imgToPolys below does just that - it's essentially the same as Szabolcs' code but I use ImageValue instead of creating an interpolating function from the image data.
Of course, some of the polygons produced this way are the "holes" in letters. In order to display the text properly we need to identify which polygons are holes and which are "solids" (for want of a better word). The function findHoles takes a list of polygons and uses the undocumented function Graphics`Mesh`InPolygonQ to test whether the first point of each polygon lies inside any of the other polygons. I've assumed that any "holes" are completely contained within a surrounding "solid", so that testing a single point is sufficient. The expression returned by findHoles is a list of {solids, holes}.
imgToPolys[img_Image] :=
Module[{w, h, rp},
{w, h} = ImageDimensions[img];
rp = RegionPlot[
ImageValue[img, {x, y}] < 0.5, {x, 0.5, w - 0.5}, {y, 0.5, h - 0.5},
PlotPoints -> 100];
Cases[Normal[rp], l_Line :> Polygon @@ l, -1]];
findHoles[p : {_Polygon ..}] := Module[{inq, holes, solids},
inq = Outer[Graphics`Mesh`InPolygonQ, p, p[[All, 1, 1]], 1];
holes = DeleteCases[inq ~Position~ True , {x_, x_}][[All, 2]];
solids = Complement[Range[Length[p]], holes];
{p[[solids]], p[[holes]]}];
Here's an example where I have shown the holes in white, so they look like, well, holes.
input = Style["{##}&/@", Bold, FontFamily -> "Calibri", FontSize -> 12];
img = Rasterize[input, ImageSize -> 800] ~ColorConvert~ "Grayscale" ~
ImageResize~ 400;
{solids, holes} = findHoles@imgToPolys@img;
Graphics[{EdgeForm[Red], Yellow, solids, White, holes}]

Faster method using FilledCurve
The procedure above is rather slow, due to the RegionPlot. An alternative way to create polygons from text is from the FilledCurve primitives that can be obtained by converting via PDF (as in Vitaliy's answer). Below is some code to convert the filled curves into polygons.
The conversion is a two stage process, first the filled curves are converted to bezier curves, then the bezier curves are sampled at some number of points (default 10), and the coordinates fed into a Polygon expression.
As previously, the polygons can then be split into "solids" and "holes" using findHoles.
filledCurveToBeziers[fc_FilledCurve] := MapThread[processFCdata, List @@ fc];
processFCdata[desc_, pts_] := Module[{r, sd},
r = Range @@@
ReplacePart[
Partition[Prepend[Accumulate[desc[[All, 2]]], 0], 2, 1], {1, 1} -> 1];
sd = desc[[All, 3]] /. {0 -> 1};
MapThread[BezierCurve[pts[[#1]], SplineDegree -> #2] &, {r, sd}]];
beziersToPolygons[x_, n_: 10] :=
Module[{samples},
samples = x /. BezierCurve[data__] :> BezierFunction[data] /@ Range[0, 1, 1/n];
Polygon /@ Select[Split[Flatten[#, 1]][[All, 1]] & /@ samples, Length[#] > 1 &]];
This approach is much faster, since it completely avoids the rasterization and image processing.
{solids, holes} =
With[{fc = Cases[ImportString[ExportString[input, "PDF"]], _FilledCurve, -1]},
Transpose[findHoles@beziersToPolygons[filledCurveToBeziers@#, 10] & /@ fc]];
Graphics[{EdgeForm[Red], Yellow, solids, White, holes}]

EdgeDetectfor detecting the edges – rm -rf Jan 24 '12 at 22:49FindCurvePath(orListCurvePathPlot) orFindShortestTourwith one of its manyMethodoption values ("Greedy"?) could be of use. I don't have time to figure out a full solution now. – Szabolcs Jan 24 '12 at 23:24