You should define what is aligned from the algorithm point of view. For us, aligned means that the writing of the coins are readable such as they have a sense.
If all the coin are the same or a small set, then you can take one for each kind as a reference and compute the homography for the others: this can be an idea to fastly do it. If you have more than one coin you can do de following.
A training phase:
- Take the images of the aligned coins as reference, one per type
- Run a feature detector on them and store the descriptors
This is your database of features, it need to be quite accurate so I suggest you to use a nice feature detector (SIFT probably can do the job) and a nice matcher (take a look at GMS, in my honest opinion one of the best so far)
For every coin you would like to align you should:
- Run a feature detector
- Match the detected features with every features stored (previously, in the training phase) and count how many matched featurew you got for every coin
- Retain only the coin that have the highest number of matched features (what happen if the number is equal for, let's say, 2 coins? You should define a robust criteria...)
- Compute the homography between the found coin and the one that is processed
- Decompose the homography to obtain just the rotation matrix
- Apply the rotation matrix to the image and enjoy!
That should do the job. For the coin for which there is uncertainty you can propose a rotation angle and let the user decide which one should be applied.
HINT: You can detect features just inside the coin detecting the circle shape of the coin first and discarding all the features outside the coin to avoid some noise. This can be an improvement
I can't provide to you Python code because I use OpenCV in C++, but you can find many tutorial of every point of the bullet list. Just fuse everything together!
I hope that helped, let me know! Sorry for my english, I'm in a rush, but I hope that you understood.