# Matching shapes (especially characters) based on their histograms [closed]

I would like to find a similarity measure between two images showing characters taking into account their histograms. An image example may contain just an individual letter or it could contain several characters and look like this:

.

Can anyone please guide me through how to use calcHist function in order to feed its output to compareHist function and find a similarity measure between such images. The important point is that the characters may not look the same and may be a little bit distorted while they still remain similar.

I tried out outer approaches such as matchShapes but because they are quite often rotation invariant, they sometimes do not provide satisfactory results and letter p is then similar to letter d.

edit retag reopen merge delete

### Closed for the following reason the question is answered, right answer was accepted by sturkmen close date 2020-10-06 12:17:59.429590

what do you expect from compareHist here ? for a binary b/w image it's the same as just counting black or white pixels(can be cheaper done using countNonZero())

also look at reduce , which gives you a horizontal/vertical projection, more a 'spatial' histogram (not a 'color' based one)

maybe in the end, you need to concatenate several feature vectors, like those projections, hu-moments, a 1d flattened, downscaled version of the pixels to a large feature vector, and feed that into an SVM

( 2015-05-02 04:53:36 -0500 )edit

ok, I am still not that fluent in image processing, I presumed that calcHist would return me histograms similar to the ones presented : here but in that thread I can't seem to find a way of determining the dissimilarity measure between images. That's why I thought of calcHist and compareHist. How can I compare the outputs of reduce' to find that measure?

( 2015-05-02 05:12:58 -0500 )edit

the image in the middle (from your link) is the actual output of reduce ;) again, caldHist computes a color-histogram, while you probably wanted the spatial distribution.

you could use cv::norm(a,b); for comparison, or, for higher accuracy, train some machine-learning (like SVM on it)

( 2015-05-02 05:16:58 -0500 )edit

thanks, but now that I know it, unfortunately it seems to me that this solution with cv::reduce is not reposition invariant. My program needs to match two shapes if they are a bit distorted and repositioned :( I think I will need to stick to the matchShapes. I would be grateful if you could tell me what arguments would be best in your opinion, now I am calling the function this way: cv2.matchShapes(contours1d, contours1d2, 2, 0)` after finding contours of the characters.

( 2015-05-02 05:43:02 -0500 )edit

"My program needs to match two shapes if they are a bit distorted and repositioned" - maybe, for reduce or hausdorff distance, you need to normalize the contours, by subtracting the tl corner point from the bounding box and dividing by diameter

matchShapes is using hu-moments to compare, you already found the problem with 'p' and 'd'

( 2015-05-02 05:51:57 -0500 )edit

Can I analyse somehow the hu moments in order to determine image orientation and compare only images oriented in the same direction?

( 2015-05-02 05:56:34 -0500 )edit