基于OpenCV&Python的图像配准异常问题求助
图像配准异常问题求助
尝试使用OpenCV和Python对两张存在微小偏移的图像进行配准,随后检测二者差异。尽管检测到的关键点匹配效果看起来很好,但得到的配准图像却异常。
原始图像
图像1:
图像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)
匹配结果

图像配准与差异检测
配准代码:
aligned_image = cv2.warpAffine(image2, M[0:2, :], (image1.shape[1], image1.shape[0]))
配准后图像:
差异检测代码:
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]
差异图像:
傅里叶变换配准尝试
针对'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配准结果:
全图配准结果:
差异图像:
请问有什么解决思路吗?非常感谢!
内容的提问来源于stack exchange,提问作者Daniel Agam
相关产品推荐
相关产品推荐

