You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV&Python的图像配准异常问题求助

图像配准异常问题求助

尝试使用OpenCV和Python对两张存在微小偏移的图像进行配准,随后检测二者差异。尽管检测到的关键点匹配效果看起来很好,但得到的配准图像却异常。

原始图像

图像1:Image 1
图像2:Image 2

说明:因TIFF格式文件过大,上传的是图像截图;中心的白色圆形元素需隐藏,仅通过右上角的'15'图案即可完成图像配准。

亮度归一化预处理代码

已对图像2进行亮度归一化,使其与图像1亮度一致:

# Convert images to grayscale
img1 = cv2.cvtColor(self.img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(self.img2, cv2.COLOR_BGR2GRAY)

# crop the images to ROI - The ROI is the same for both images and is the left bottom corner in size of 1/5 of the image
img1_roi = img1[0:int(img1.shape[0] / 5), 0:int(img1.shape[1] / 5)]
img2_roi = img2[0:int(img2.shape[0] / 5), 0:int(img2.shape[1] / 5)]

# Calculate the mean of the images.
mean_img1 = np.mean(img1_roi)
mean_img2 = np.mean(img2_roi)

# Calculate the ratio of the brightness of the images.
ratio = mean_img1 / mean_img2
print(f'Brightness ratio: {ratio}')

# Multiply the second image by the ratio.
self.img2 = self.img2 * ratio

# Convert the image to uint8 again.
self.img2 = np.clip(self.img2, 0, 255)
self.img2 = self.img2.astype(np.uint8)

SIFT关键点配准主代码

image1 = cv2.cvtColor(self.img1, cv2.COLOR_BGR2GRAY)
image2 = cv2.cvtColor(self.img2, cv2.COLOR_BGR2GRAY)
height, width = image2.shape

sift = cv2.xfeatures2d.SIFT_create()

keypoints1, descriptors1 = sift.detectAndCompute(image1, None)
keypoints2, descriptors2 = sift.detectAndCompute(image2, None)

bf = cv2.BFMatcher()

matches = bf.knnMatch(descriptors1, descriptors2, k=2)

good_matches = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good_matches.append(m)
src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

draw_params = dict(singlePointColor=None, flags=2)
img3 = cv2.drawMatches(image1, keypoints1, image2, keypoints2, good_matches, None, **draw_params)

匹配结果

Matches output

图像配准与差异检测

配准代码:

aligned_image = cv2.warpAffine(image2, M[0:2, :], (image1.shape[1], image1.shape[0]))

配准后图像:Aligned image

差异检测代码:

difference = cv2.absdiff(image1, aligned_image)
threshold = 10  # Adjust this threshold as per your requirements
change_mask = cv2.threshold(difference, threshold, 255, cv2.THRESH_BINARY)[1]

差异图像:Difference image

傅里叶变换配准尝试

针对'15'图案的ROI尝试了傅里叶方法:

def _correlate_images(self, image1, image2):
    # compute the correlation coefficient between two images
    correlation = signal.correlate2d(image1, image2, boundary='symm', mode='same')
    return correlation

def _compute_shift_distance(self, image1, image2):
    # compute the shift distance between two images
    correlation = self._correlate_images(image1, image2)
    (y, x) = np.unravel_index(correlation.argmax(), correlation.shape)
    (tH, tW) = image2.shape[:2]
    shift_distance = (x - tW // 2, y - tH // 2)
    return shift_distance

def _align_images_fourier_mellin(self, image1, image2):
    # align images using Fourier-Mellin transform

    # compute the Fourier Transform of both images, then compute the
    # magnitude spectrum
    fft1 = np.fft.fft2(image1)
    fft2 = np.fft.fft2(image2)
    magnitude_spectrum1 = 20 * np.log(np.abs(fft1))
    magnitude_spectrum2 = 20 * np.log(np.abs(fft2))

    # find the peak in the correlation map
    correlation = self._correlate_images(magnitude_spectrum1, magnitude_spectrum2)
    (x, y) = np.unravel_index(correlation.argmax(), correlation.shape)

    # compute the shift distance
    (delta_x, delta_y) = self._compute_shift_distance(image1, image2)

    # use the shift distance to translate the image
    M = np.float32([[1, 0, delta_x], [0, 1, delta_y]])
    shifted = cv2.warpAffine(image2, M, (image2.shape[1], image2.shape[0]))

    # return the aligned image
    return shifted


image1_roi = image1[int(height / 5.5):int(height / 2.5), int(2.5 * width / 4):width]
image2_roi = image2[int(height / 5.5):int(height / 2.5), int(2.5 * width / 4):width]
aligned_image = self._align_images_fourier_mellin(image1_roi, image2_roi)

傅里叶方法结果

ROI配准结果:aligned image by Fourie
全图配准结果:aligned full image by Fourie
差异图像:Fourie diffs

请问有什么解决思路吗?非常感谢!

内容的提问来源于stack exchange,提问作者Daniel Agam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:06:59