I have a proof of concept.
- center the template on the eye of the arrow
- create rotated filter instances (
getRotationMatrix2D
,warpAffine
). that’s a “filter bank”. matchTemplate
withTM_SQDIFF
for every filter in the bank (yes that’s expensive, takes half a second). best results are minima (least difference).- non-maximum suppression (using
dilate
in case of maxima, orerode
in case of minima, and then equality comparison) - also thresholding on a manually chosen threshold
- for each extremum, get index (thus angle) of filter with best response (
np.argmin
)
I get a heading of 306°, or 54° counter-clockwise, for your picture. testing 1° steps took me 4-5 seconds (10° steps take half a second). this could probably be done quicker, with some tricks.
convolution/correlation (filter2D
) turned out to be bad at this, even if they’re fast at this. these “signals” contain DC components, which always throws simple multiplication off. TM_SQDIFF uses the sum of squared differences, which models the situation a lot better.
it’s doable. I’ll let you puzzle over the details this. the list above should suffice.
visible here: