Measuring a very small image rotation

This is an algorithm approach question, more than a code question. Say I have an image of part of an encoder wheel; maybe it’s also in better focus and less noisy than my first attempt here. This pattern can rotate around a known, fixed center point which is above the image frame, but nominally that is the only motion expected. Given two such images that are different by a very small rotation, maybe equivalent to a few pixels or less, what technique would be expected to most reliably resolve and measure the smallest rotation? There’s always going to be some image noise and encoder imperfections so I’d like to use all the image pixels that can usefully contribute to the estimate. My first impulse was to remap the images from cylindrical coordinates (with origin at the known center of rotation) to cartesian coordinates, and then find a simple 1-D correlation peak between the two resulting remapped images. Would it be somehow better to try to solve for the lines that form the edges of each radial stripe? Is there some way in OpenCV to use a line-finding algorithm with the constraint that all the lines pass through the same point?
Note: I don’t need to measure rotations larger than one line-space pair, this is about resolving very tiny, few-pixel-or-less differences.

depends on what I’m seeing there.

is the code wheel parallel to the surface it’s projected on?

is the camera perpendicular to (looking straight at) the projection surface?

if those are given, that’d make the whole geometry very easy. if just the camera is misaligned, that can be fixed with homography. if the code wheel and projection surface aren’t parallel, that’s another homography (to undo/rectify that projection).

given all is fine, I’d apply an ECC refinement/estimation. that will respect all image pixels. the resulting homography should then purely encode the (in-plane) rotation of the wheel (around some center of rotation).

if the projection surface is dotted with splotches, that would be a problem. you don’t want to just threshold the image because that ruins edge pixel information. you’d want to identify the grayscale range where those speckles appear, and remove those, while not affecting the range of the shadow/light pixels.

typically, code wheels are evaluated using sensors specifically made for the task. some of these can resolve better than quadrature steps.

1 Like

Interesting problem. How much computational power do you have at your disposal, and what kind of update rate do you need? And what kind of resolution do you need?

Some thoughts right out of the gate:

  1. What Crackwitz suggested might be the easiest/best approach if the assumptions are met and you can afford the computational cost. I don’t have much experience with that, but it seems like a good (and more general) approach to the ad-hoc stuff I’m likely to suggest.
  2. Resolving “few-pixel-or less” differences should be trivial. Since you have so much data to work with, I would expect subpixel locations would be easy to achieve in principle.
  3. I’m always a bit wary of doing any image remapping / undistortion / etc when I care about measurements. I don’t know if this bias is well founded, but I tend to do the image processing / calculations in raw image space and then correct the results vs doing the image processing/calculations on a warped image.
  4. I might start by analyzing some very specific and small image ROIs - like pick the area where the line is vertical in image space and make an ROI at the top (where the slit meets the wheel) and at the bottom of that same line…do image processing on those two areas to find the edge. Once you have located two endpoints you could march along the line that connects them and find the edge position at each step. Fit a line, calculate the angle…repeat for as many edges as you need (and can afford to process). But I’m already optimizing for performance, and you might not care about that.

Probably best to try what Crackwitz suggests and see if you can get the accuracy you need. If you can but need better performance, maybe you can try the same approach but with a handful of ROIs to reduce computational cost.

Good luck!

instead of warping images followed by ECC refinement, the ECC refinement can be calculated first, on source images, and any misalignment of planes/axes can be compensated onto the homography matrix that came out of ECC refinement.

I cannot predict how well ECC will do. you should try different approaches and compare actual numbers. if you can measure the code wheel’s angle with any mechanical tool, that’d be good to have as a gold standard.

oh and remember, images usually have gamma compression applied to them, so the color space isn’t linear (behavior of pixels on edges…). make it linear, then all the calculations will become more accurate.

1 Like

Thank you very much for these well-informed and useful replies! I was not aware of the OpenCV findTransformECC() prior to your comment. Given that it is not limited to any specific pattern, I tried it on a number of pairs of nearly but not quite aligned camera images of a random textured surface. When swapping the template and the test image within a pair, I find almost but not quite exactly opposite rotation and offset values, as I would expect. I have not yet compared with physical measurements, but these reversed-pair results are generally self-consistent within about 0.005 pixels in x,y offset and 0.5 arc-seconds (0.00014 degrees) of rotation, using 1920x1080 images from a cheap camera. That may represent some lower bound on the real repeatability and resolution achievable with this setup, but that is as good as I had hoped for. My application is just for a one-time manual comparison, so I can use plenty of CPU power (although it is usually only ~1 second, even without pyramidal resolution scaling speedups). There are certainly commercial rotary encoders with 1 arc-second resolution or better, but they are not cheap.

keep in mind that since this is a periodic signal (code wheel, rotational symmetry), there’s a good chance that any of these methods can latch onto a solution that isn’t the smallest required motion, nor the best possible fit.

the motion between two pictures should be small enough. a quarter period is ideal. at half a period, you already get ambiguity.

I gather you’re interested in small motion, so that shouldn’t become an issue in practice.