How to extract a stroke from a Chinese character
I've been trying many times to create an algorithm to extract stroke information from Chinese characters. I've tried various methods but none was very satisfying, probably because of my limited knowledge of graphics algorithms in general.
Basically, I have the following data:
The 开发者_Python百科Chinese character, which can be either pixels or vector (in black)
The overall outline of the stroke, in pixels (in red)
An overall direction (the blue arrows).
From this, I'm trying to extract the stroke. If you had to do this, given the available data, what methods would you use? Can you think of any automatic way to extract the stroke?
I'd start with calculating the distance to the nearest white pixel from each blue pixel. Then you can keep all the red pixels which are closer than the nearest white pixel. The effect may be smoothed with some filter afterwards (maybe something like an erosion followed by a close).
You might be looking for the medial axis, also known as the topological skeleton. In short, you will solve to find all points that are equidistant to more than one point on the edge. You may need to do some smoothing or simplification of the resultant curve.
The tricky part is separating the part of the shape that's common to more than one stroke. I'm not convinced that there's a well-defined way to do that. Perhaps define the "common region" as the circle centered on each skeleton intersection, tangent to the nearest edges? Then maybe some interpolation of stroke width across the gap?
I don't think you can come up with an algorithm that doesn't have cases where it would be incorrect. There are parts of some characters that are the same but do not equate to the same stroke count. For example, 馬 technically also includes 口 from a visual standpoint (not lingusitical, of course).
The only idea I have is to sepearate the area into small regions and write an algorith that would attempt to follow the set order in which strokes are make, but I can't imagine that would be easy, and depending on the font, some lines are extended into regions they shouldn't be in.
There are also some characters that simply wouldn't work well with the algorithm due to their unusual layout - only by following the strict rules of the order of strokes can you get to the correct number: examples include 凹 and 凸.
I have to ask--stroke count is basic information for each character - why would you need to create an algorithm to count it? Wouldn't it be easier to do character recognition and just look up the stroke count for the character in a custom dictionary?
From the blue line and the sample image I think this three step approach might work for quite a few cases:
For each point along the line, select all red pixels that are closer to that point than the closest white pixel. This will roughly give you the stroke of the character, but with bulges around area's where two strokes cross, and you will exclude some pixels at both ends of the stroke.
To eliminate the bulges, isolate the edge pixels of the stroke, and compute the hough transform for that edge-image. Select the two most significant lines from that. This will give you (if the stroke is sufficiently straigh) two lines along the edges of the stroke. Eliminate all red pixels from your stroke that are further away from the blue line in a perpendicular direction than these two lines. Now (for a sufficiently straight stroke) all you are missing will be some small isolated lumps of pixels that hapened to be eliminated either in step 1 or step 2 so:
Add all small isolated regions of pixels that touch just your stroke, and no other part of the character to the stroke. If the lines you find in step 2 are too close to the blue line you could also perform this step between steps 1 and 2.
I think the simplest possible thing that can work is to:
- plot the blue arrows, one by one
- compute the distance transform of each blue line segment
- intersect this discrete distance with the red areas
- remove red areas with distance to the blue segment greater than T
Once you get this done, you can then work on more sophisticated strategies to select a good, segment dependent T.
精彩评论