Как я могу сделать обнаружение изменений с помощью K-Means и разностного изображения? - PullRequest
0 голосов
/ 15 марта 2019

Я использую эту статью Комбинированная разностная картина и кластеризация k-средних для обнаружения изменения изображения SAR

И я генерирую этот код на основе рабочего процесса:

import cv2
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import euclidean_distances

# Define name of saving file and string
year1 = "2018"
year2 = "2019"
fileExtension = ".png"
halfFileName = year1 + "-" + year2 + fileExtension
folder = "/Volumes/MACHD/OneDrive/Ultima/"
combinedImageName = folder + "CombineImage" + halfFileName
differenceClusteredImageName = folder + "CombineImageClustered" + halfFileName
changeMapImageName = folder + "ChangeMap" + halfFileName
changeMapOnImageName = folder + "ChangeMapOnImage" + halfFileName

# Function for image reconstruction
def recreate_image(codebook, labels, w, h):
    """Recreate the (compressed) image from the code book & labels"""
    d = codebook.shape[1]
    image = np.zeros((w, h, d))
    label_idx = 0
    for i in range(w):
        for j in range(h):
            image[i][j] = codebook[labels[label_idx]]
            label_idx += 1
    return image

# Opening images
image1 = cv2.imread('/Users/myname/Downloads/AICDDataset/Images_NoShadow/Scene0024_View03_target.png')
image1 = cv2.resize(image1,dsize=(819,726), interpolation=cv2.INTER_CUBIC)
image1Denoised = cv2.fastNlMeansDenoising(image1)
image1Gray = cv2.cvtColor(image1Denoised,cv2.COLOR_RGB2GRAY)
print(image1.size)
image2 = cv2.imread('/Users/myname/Downloads/AICDDataset/Images_NoShadow/Scene0024_View03_moving.png')
image2 = cv2.resize(image2,dsize=(819,726), interpolation=cv2.INTER_CUBIC)
image2Denoised = cv2.fastNlMeansDenoising(image2)
image2Gray = cv2.cvtColor(image2Denoised,cv2.COLOR_RGB2GRAY)

# Subctration images
subtractionImage = image1Gray - image2Gray
subtractionImageMean = cv2.blur(subtractionImage,(9,9))

# Ratio images with logarithmic subtraction
image1Log = np.uint8(np.log1p(image1Gray))
image2Log = np.uint8(np.log1p(image2Gray))
normalizedImage1 = cv2.normalize(image1Log, None, 0, 255, cv2.NORM_MINMAX, dtype = cv2.CV_8U)
normalizedImage2 = cv2.normalize(image2Log, None, 0, 255, cv2.NORM_MINMAX, dtype = cv2.CV_8U)
subtractionImageLog = image2Log - image1Log
subtractionImageLogMedian = cv2.medianBlur(subtractionImageLog,9)
# Combination of image
alpha = 0.5
combinedImage = (alpha * subtractionImageMean) + ((1-alpha) * subtractionImageLogMedian)
cv2.imwrite(combinedImageName,combinedImage) #saving to png

# Load Image and transform to a 2D numpy array.
w, h = original_shape = tuple(image1Gray.shape)
combinedImageFloat = np.float64(combinedImage/255)
combinedImageArray = np.reshape(combinedImageFloat,(w * h, 1))
# Clustering
km = KMeans(n_clusters=2, random_state=0).fit(combinedImageArray)
#kmPredict = km.predict(combinedImage)

# Clustered Image reconstruction
differenceClustered = (km.cluster_centers_[km.labels_] * 255).astype(np.uint8).reshape(w, h)
differenceClusteredImage = differenceClustered.reshape((combinedImage.shape))
cv2.imshow('Difference Clustered',differenceClusteredImage)
cv2.imwrite(differenceClusteredImageName,differenceClusteredImage)
# Thresholding
th,changeMap = cv2.threshold(differenceClusteredImage,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(th)
cv2.imshow('Change Map',changeMap)
cv2.imwrite(changeMapImageName,changeMap)

# Make pixel on image
changeMap = cv2.resize(changeMap,dsize=(824,791),interpolation=cv2.INTER_CUBIC)
changePosition = np.argwhere(changeMap == 0)
print(changePosition.size)
image2C = image2
for pos in changePosition:
    cv2.rectangle(image2C,(pos[0],pos[1]),(pos[0],pos[1]),(0,255,0),3)
cv2.imwrite(changeMapOnImageName,image2C)
cv2.imshow('Change', image2C)

# Percentage Of changes
changePercentage = (changePosition.size / image1.size) * 100
print("Anni: " + year1 + " " + year2)
print("Change percent is: " + str(changePercentage) + " %")

Когда я запускаю свой код, я получаю следующие результаты:

  • 1783782 количество пикселей первого изображения
  • порог, выбранный Otsu: 14,0
  • 831074 количество пикселей изменено
  • Процент изменений: 46,59055871177083%

Я применяю алгоритм к этому набору данных: Набор данных для обнаружения изменений , используя "Scene0024_View03_target.png" и "Scene0024_View03_moving.png "и из набора данных карта изменений, которую я должен получить: ground truth change map

Но алгоритм дает мне такие результаты:

[combination of difference images]

, которые показывают комбинацию изображений после того, как на этих изображениях я использую алгоритм Sklearn K-Means для кластеризации изображения в два кластера: изменить и оставить без изменений, и результат, который я получаю:

[combination of difference images clustered]

На тКластеризованные изображения. Я применяю алгоритм порогового определения openCV с использованием OTSU и получаю карту изменений:

[change map after K-Means]

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

Зеленый пиксель на втором изображении, чтобы показать обнаружение изменений, где

и я не понимаю, почему происходит это вращение.

Прошу вас, пожалуйста, помочь мне.

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