Кадрируйте спутниковое изображение на основе исторического изображения с OpenCV в Python - PullRequest
0 голосов
/ 24 марта 2020

У меня следующая проблема, у меня есть пара из двух изображений: одно историческое и одно современное спутниковое изображение, и поскольку историческое изображение охватывает меньшую область, я хочу обрезать спутниковые изображения. Здесь можно увидеть код, который я написал для этого:

import numpy as np
import cv2
import os
import imutils
import math

entries = os.listdir('../')

refImage = 0
histImages = []
def loadImage(index):
    referenceImage = cv2.imread("../" + 'ref_' + str(index) + '.png')

    top = int(0.5 * referenceImage.shape[0])  # shape[0] = rows
    bottom = top
    left = int(0.5 * referenceImage.shape[1])  # shape[1] = cols
    right = left

    referenceImage = cv2.copyMakeBorder(referenceImage, top, bottom, left, right, cv2.BORDER_CONSTANT, None, (0,0,0))
    counter = 0
    for entry in entries:
        if entry.startswith("image_"+str(index)):
            refImage = referenceImage.copy()
            histImage = cv2.imread("../" + entry)
            #histImages.append(img)
            points = np.loadtxt("H2OPM/"+"CP_"+ entry[6:9] + ".txt", delimiter=",")

            vector_image1 = [points[0][0] - points[1][0], points[0][1] - points[1][1]] #hist
            vector_image2 = [points[0][2] - points[1][2], points[0][3] - points[1][3]] #ref

            angle = angle_between(vector_image1, vector_image2)

            hhist, whist, chist = histImage.shape

            rotatedImage = imutils.rotate(refImage, angle)

            x = int(points[0][2] - points[0][0])
            y = int(points[1][2] - points[1][0])

            crop_img = rotatedImage[x+left:x+left+hhist, y+top:y+top+whist]

            print("NewImageWidth:", (y+top+whist)-(y+top),(x+left+hhist)-(x+left))

            print(entry)
            print(x,y)


            counter += 1
            #histImage = cv2.line(histImage, (points[0][0], ), end_point, color, thickness) 
            cv2.imwrite("../matchedImages/"+'image_' + str(index) + "_" + str(counter) + '.png'  ,histImage)
            #rotatedImage = cv2.line(rotatedImage, (), (), (0, 255, 0), 9) 
            cv2.imwrite("../matchedImages/"+'ref_' + str(index) + "_" + str(counter) + '.png'  ,crop_img)

Сначала я загружаю исходное спутниковое изображение и дополняю его, чтобы не потерять информацию из-за поворота, во-вторых, я загружаю один из сопоставленные исторические изображения, а также совпадающие ключевые точки двух изображений (то есть список x_hist, y_hist, x_present_day, y_present_day). В-третьих, я вычисляю угол поворота между двумя изображениями (который работает), и в-четвертых, я обрезаю изображение (и в-пятых, я сохраняю изображения).

Проблема : Как указано вращение работает нормально, но моя программа обрезает неправильную часть изображения.

Я думаю, что из-за поворота границы (то есть слева, справа, сверху, снизу) больше не правильные, и я думаю, Вот где моя проблема, но я не уверен, как решить эту проблему.

Информация, которая может помочь:

  • Оба изображения масштабированы таким же образом (таким образом, один пиксель = прибл. 1 м)
  • У меня есть как минимум 6 ключевых точек для каждого изображения

Ответы [ 2 ]

0 голосов
/ 27 марта 2020

Итак, я нашел ошибку в моих вычислениях. Ограничительные рамки области выреза были ошибочно преобразованы в современное изображение.
Итак, это:

x = int(points[0][2] - points[0][0])
y = int(points[1][2] - points[1][0])

было заменено на это:

v = [pointBefore[0],pointBefore[1],1]
# Perform the actual rotation and return the image
calculated = np.dot(m,v)
newPoint = (int(calculated[0]- points[0][0]),int(calculated[1]- points[0][1]))

где m (= М) из преобразования:

def rotate_bound(image, angle):
    # grab the dimensions of the image and then determine the
    # center
    (h, w) = image.shape[:2]
    (cX, cY) = (w // 2, h // 2)

    # grab the rotation matrix (applying the negative of the
    # angle to rotate clockwise), then grab the sine and cosine
    # (i.e., the rotation components of the matrix)
    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])

    # compute the new bounding dimensions of the image
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))

    # adjust the rotation matrix to take into account translation
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY

    # perform the actual rotation and return the image
    return cv2.warpAffine(image, M, (nW, nH)), M

Спасибо.

0 голосов
/ 24 марта 2020

Я еще не посмотрел ваш код, но будет ли это из-за того, что вы перепутали x и y? Проверьте документацию OpenCV, чтобы убедиться, что импортируемые переменные находятся в правильном порядке. В течение моего ограниченного времени и опыта работы с opencv, это довольно странно, потому что иногда он запрашивает, например, BGR вместо значений RGB. (В моей программе, а не в вашей)

Кроме того, у вас, похоже, есть несколько списков, убедитесь, что список [x] [y] не перепутан как список [y] [x]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...