this is not my code, i found it into another question, i try it and work very well. This is the code:
import cv2
import os
import numpy as np
def findCenter(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th, threshed = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
_, cnts, hierarchy = cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
M = cv2.moments(cnts[0])
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
return (cX, cY)
img1 = cv2.imread("Path of the image you want to copy")
img2 = cv2.imread("Path of the image you want to use like a backgroud")
pt1 = findCenter(img1)
pt2 = findCenter(img2)
## (2) Calc offset
dx = (pt1[0] - pt2[0])
dy = (pt1[1] - pt2[1])
h, w = img2.shape[:2]
dst = img1.copy()
dst[dy:dy + h, dx:dx + w] = img2
cv2.imwrite(path + roi, dst)
This is the original answer: Match center of two images (OpenCV, Python)
Here is my result using numpy and OpenCV:
- Find the coords in object
- Calc the moment center of the object's coords
- Calc the moment center offset (from src to dst)
- Adjust the coord with offset
- Do slice op
The result:
(1) object :
(2) cross background:
(3) object on the cross background:

Are they all going to be letters (or even H's)?
There are a few ways to approach this. The fastest (but most naive) way would be to find the left-most and right-most black pixels, and then center at the halfway point. Then do the same vertical. Basically create a bounding box to your image, where you filter on anything that isn't #FFFFFF
Again, depends on the data though.
You can also use Scikit image to find the image's centre of mass (or you're own function) and then translate the image using padding? A basic way of doing this in Python would be:
im = numpy.zeros((20, 20))
im[2:6, 2:14] = 1
# Determine Centre of Mass
com = ndimage.measurements.center_of_mass(im)
print(com)
# Translation distances in x and y axis
x_trans = int(im.shape[0]//2-com[0])
y_trans = int(im.shape[1]//2-com[1])
# Pad and remove pixels from image to perform translation
if x_trans > 0:
im2 = numpy.pad(im, ((x_trans, 0), (0, 0)), mode='constant')
im2 = im2[:im.shape[0]-x_trans, :]
else:
im2 = numpy.pad(im, ((0, -x_trans), (0, 0)), mode='constant')
im2 = im2[-x_trans:, :]
if y_trans > 0:
im3 = numpy.pad(im2, ((0, 0), (y_trans, 0)), mode='constant')
im3 = im3[:, :im.shape[0]-y_trans]
else:
im3 = numpy.pad(im2, ((0, 0), (0, -y_trans)), mode='constant')
im3 = im3[:, -y_trans:]
print(ndimage.measurements.center_of_mass(im3))