如何使用K均值和差异图像进行变化检测?

时间:2019-03-15 06:39:58

标签: python image opencv k-means image-thresholding

我使用本文Combined difference image and k-means clustering for SAR Image Change Detection

然后我根据工作流程生成此代码:

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第一张图像的像素数
  • 大津选择的
  • 阈值:14.0
  • 831074像素数已更改
  • 变化百分比是:46.59055871177083%

我将算法应用于以下数据集:DataSet for Change Detection 使用“ Scene0024_View03_target.png”和“ Scene0024_View03_moving.png”,并从数据集中获得的变更图是: ground truth change map

但是算法给了我这个结果:

[combination of difference images]

在这些图像上显示图像的组合之后,我使用sklearn的K-Means算法将图像分为两个聚类:变化和不变,而我得到的结果是:

[combination of difference images clustered]

在聚类图像上,我使用OTSU应用openCV的阈值算法,其变化图为:

[change map after K-Means]

我的变更图不等于基本事实。我不明白我在哪里犯错。 另外,当我尝试将绿色点放置在有更改的位置时,我得到了这样的更改轮换:

第二张图像上的绿色像素显示变化检测在哪里

我不明白为什么会有这种轮换。

我请你帮我。

0 个答案:

没有答案