【问题标题】:Find orientation of object using PCA使用 PCA 查找对象的方向
【发布时间】:2017-09-08 05:37:32
【问题描述】:

我想在附加的图像中找到明亮物体的方向。为此,我使用了主成分分析 (PCA)。

在图像 1 的情况下,PCA 找到正确的方向,因为第一个主成分在该方向上对齐。然而,在图像 2 的情况下,主成分是迷失方向的。

谁能解释为什么 PCA 在两张图片中显示不同的结果?另外,请建议是否有其他方法可以找到对象的方向。

import os
import gdal
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import skimage
from skimage.filters import threshold_otsu
from skimage.filters import try_all_threshold
import cv2
import math
from skimage import img_as_ubyte
from skimage.morphology import convex_hull_image
import pandas as pd  

file="path to image file"

(fileRoot, fileExt)= os.path.splitext(file)

ds = gdal.Open(file)
band = ds.GetRasterBand(1)
arr = band.ReadAsArray()
geotransform = ds.GetGeoTransform()   
[cols, rows] = arr.shape
thresh = threshold_otsu(arr)
binary = arr > thresh
points = binary>0
y,x = np.nonzero(points) 
x = x - np.mean(x)
y = y - np.mean(y)
coords = np.vstack([x, y])
cov = np.cov(coords)
evals, evecs = np.linalg.eig(cov)
sort_indices = np.argsort(evals)[::-1]
evec1, evec2 = evecs[:, sort_indices]
x_v1, y_v1 = evec1  
x_v2, y_v2 = evec2
scale = 40
plt.plot([x_v1*-scale*2, x_v1*scale*2],
         [y_v1*-scale*2, y_v1*scale*2], color='red')
plt.plot([x_v2*-scale, x_v2*scale],
         [y_v2*-scale, y_v2*scale], color='blue')
plt.plot(x,y, 'k.')
plt.axis('equal')
plt.gca().invert_yaxis()  
plt.show()
theta = np.tanh((x_v1)/(y_v1))  * 180 /(math.pi)

【问题讨论】:

  • 原始图像是'tiff'格式并带有地理坐标信息,为此目的'gdal'用于读取数组'arr'中的图像。但是附加的图像是“png”格式,可以直接在数组中读取。请保重。提前致谢!
  • 如果我正确理解您的代码,您将使用图像中的所有点来获取方向,而不仅仅是主要的白色区域。?
  • 看起来像点密度的问题...第二个图像对象要小得多,噪声点以相对较大的密度分散,所以如果您不只为 PCA 选择对象点那么你的结果会被扭曲......顺便说一句,如果大约 OBB 就足够了,你可以使用这个How to Compute OBB of Multiple Curves?
  • @Amitay Nachmani 感谢您的交流!我使用 otsu 阈值计算二进制图像以提取所有白色区域点。然后将这些点用于计算 PCA。因此,只有白色区域像素用于计算方向。
  • @Spektre 感谢您的评论!只有白色区域像素用于计算方向。

标签: image-processing rotation orientation pca


【解决方案1】:

您声称您只使用了白色像素。您是否检查了某些叠加渲染选择了哪些?无论如何,我认为这还不够,尤其是对于您的第二张图像,因为它不包含任何完全饱和的白色像素。我会在 PCA 之前使用更多处理。

  1. 增强动态范围

    您当前的图像不需要此步骤,因为它们包含黑色和几乎完全饱和的白色。此步骤允许在更多样本输入图像之间统一阈值。欲了解更多信息,请参阅:

  2. 流畅一点

    这一步将显着增加噪声点的强度并平滑较大对象的边缘(但将它们缩小一点)。这可以通过任何 FIR 滤波器或卷积或高斯滤波来完成。有些人还为此使用形态运算符。

  3. 强度阈值

    这将去除较暗的像素(清晰到黑色),从而完全去除噪点

  4. 通过形态学算子将剩余的物体放大回原来的大小

    您可以通过将生成的 OBB 放大几个像素来避免这种情况(数字与 #2 中的平滑强度绑定)。

  5. 现在应用 OBB 搜索

    您正在使用 PCA,因此请使用它。我改用这个:

当我使用上述方法(没有 #4)尝试您的图片时,我得到了以下结果:

我注意到您的第二张图片的另一个问题是其中的白色像素不多。这可能会显着偏向 PCA,尤其是在没有预处理的情况下。我会尝试通过双三次过滤放大图像并将其用作输入。可能这是您遇到的唯一问题。

【讨论】:

  • 与您的建议类似,我在 otsu 阈值图像上使用凸包(来自 skimage.morphology )来放大对象作为预处理步骤。在这种情况下,PCA 也不起作用。
  • 您可能在解释 PCA 时遇到问题。它为您提供在某些情况下不需要是对象本身的方向的主要组件。你能分享预处理的输入图像和错误找到的方向吗?它可能会对此有所启发。无论如何,您仍然可以像我一样使用几何方法。虽然精度仅限于初始角度表大小,但可以递归增强,无需处理整个圆范围。
猜你喜欢
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
相关资源
最近更新 更多