Вычисление карты корреляции областей с помощью opencv и python

#python #opencv #image-processing #correlation

#python #opencv #обработка изображений #корреляция

Вопрос:

Итак, я работаю над проектом обработки изображений, моя цель — обнаружить дублирующиеся области на изображении с помощью SIFT и аффинного преобразования, я уже нахожусь в точке, где у меня есть правильное сопоставление ключевых точек и матрица аффинного преобразования.

Тогда я застрял на этом шаге прямо сейчас, где мне нужно сгенерировать 2 корреляционных растровых изображения, используя это 2 изображения, которые я получил после аффинного преобразования:

на этом рисунке показана формула для корреляции

на этом рисунке вы можете увидеть, как это должно выглядеть

и эти два изображения, с которыми я работаю:

gray_img

wrapaffine_img

Итак, мне нужна помощь в том, как я могу сделать этот шаг, я попробовал, но, к сожалению, у меня не получилось. Я попробовал скользящие окна обоих изображений, и я взял 5×5 пикселей, и это означает, что, возможно, я все сделал неправильно, я знаю, что скользящее окно ужасно, но я просто пробую что-то в данный момент. это то, что я получил до сих пор, но мне нужно обратное

мой результат

Я попробовал это

 # Black image filled up with zeros
blank_image = np.zeros((h, w, 1), np.uint8)

for y in range(0, h-4):
    for x in range(0, w-4):
        window1 = img_gray[y: y 5, x: x 5]
        window2 = wrapAffine_img[y: y   5, x: x   5]
        a1 = window1[3][3]
        a2 = window2[3][3]
        mean1 = cv2.mean(window1)
        mean2 = cv2.mean(window2)
        mean1_num = mean1[0]
        mean2_num = mean2[0]
        b1 = a1 - mean1_num
        b2 = a2 - mean2_num
        top = (b1*b2)
        bottom = math.sqrt((b1*b1)*(b2*b2))

        if bottom > 0:
            print(top/bottom)
            intensity = top/bottom
            blank_image[y   2, x   2] = intensity
        elif bottom <= 0:
            intensity = 0
            blank_image[y 2, x 2] = intensity
 

это мой код, который работает:

 import cv2
import numpy as np
import matplotlib.pyplot as plt

# 1) Read in the image
img = cv2.imread("040_F.png")
#img_gray = cv2.imread("original_golden_bridge.jpg", cv2.IMREAD_GRAYSCALE)

# Original image parameters: Height, Width, channel
h, w, c = img.shape

# 2) RGB image convert to grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 3) Initiate SIFT detector (nfeatures = "keypoints number")
sift = cv2.SIFT_create(nfeatures=100000, nOctaveLayers=7, sigma=1.6)
# 4) Find the keypoints and descriptors with SIFT
keypoints, descriptors = sift.detectAndCompute(img_gray, None)

# # Number of the keypoints
# print(len(keypoints))
#
# # 4.1) Draw out keypoints, FLAG is for vector size and direction (optional)
# img = cv2.drawKeypoints(img_gray, keypoints, img, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#
# # 4.2) Show image or save out in a file (optional)
# cv2.imshow("result", img)
# cv2.imwrite('keypoints.png', img)

# 5) Create Brute-Force Matcher,
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=False)

# 5.1) Brute-Force with KNN, K the number of best matches
matches = bf.knnMatch(descriptors, descriptors, k=3)

# 5.2) Removing self matching points
better_matches = []
for a, b, c in matches:
    if a.trainIdx == a.queryIdx:
        better_matches.append([b, c])
    elif b.trainIdx == b.queryIdx:
        better_matches.append([a, c])
    elif c.trainIdx == c.queryIdx:
        better_matches.append([a, b])

# 5.3) Apply ratio test
ratio_thresh = 0.5
good_matches = []
for m, n in better_matches:
    if m.distance < ratio_thresh * n.distance:
        good_matches.append(m)

# 5.4) Affine Transform with RANSAC
MIN_MATCH_COUNT = 3
if len(good_matches) > MIN_MATCH_COUNT:
    src_pts = np.float32([keypoints[m.trainIdx].pt for m in good_matches])
    dst_pts = np.float32([keypoints[m.queryIdx].pt for m in good_matches])

    retval, inliers = cv2.estimateAffine2D(src_pts, dst_pts, method=cv2.RANSAC, ransacReprojThreshold=3, maxIters=100,
                                           confidence=0.99)

    matchesMask = inliers.ravel().tolist()

# 5.5) Filter with RANSAC
final_matches = []
for i in range(len(good_matches)):
    if matchesMask[i] == 1:
        final_matches.append(good_matches[i])

# 5.3.1) Draw Lines and circles on the image (optional)
# Grayscale image convert to RGB image
img_RGB = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)

list_point1 = []
list_point2 = []
for j in final_matches:

    # Get the matching keypoints for each of the images
    point1 = j.trainIdx
    point2 = j.queryIdx

    # Get the coordinates, x - columns, y - rows
    (x1, y1) = keypoints[point1].pt
    (x2, y2) = keypoints[point2].pt

    # Append to each list
    list_point1.append((int(x1), int(y1)))
    list_point2.append((int(x2), int(y2)))

    # Draw a small circle at both co-ordinates: radius 4, colour green, thickness = 1
    # copy keypoints circles
    cv2.circle(img_RGB, (int(x1), int(y1)), 4, (0, 255, 0), 1)
    # original keypoints circles
    cv2.circle(img_RGB, (int(x2), int(y2)), 4, (0, 255, 0), 1)

    # Draw a line in between the two points, thickness = 1, colour green
    cv2.line(img_RGB, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 1)


# 6) Computing region correlation map
# 6.1) WrapAffine
wrapAffine_img = cv2.warpAffine(img_gray, retval, (w, h))
cv2.imwrite('res.png', wrapAffine_img)


# 3) Output
cv2.imshow("result", res)
cv2.imwrite('final_matches.png', res)
#cv2.imshow("corelation", img_correlation_map)
cv2.waitKey(0)
cv2.destroyAllWindows()
 

Комментарии:

1. Привет, Кис. Пожалуйста, предоставьте минимальный воспроизводимый образец и четкое определение проблемы в коде

2. Я отредактировал свой вопрос, чтобы было ясно, что у меня есть 2 изображения, и я хочу вычислить карту корреляции регионов с ними, используя формулу на картинке.