使用Python

时间:2015-11-27 23:29:32

标签: python opencv computer-vision edge-detection hough-transform

我正在用Python编写一个程序来循环浏览从视频帧中提取的图像并检测其中的行。图像质量相当差,内容差异很大。这是两个例子: Sample Image 1 | Sample Image 2

我试图检测每个图像中的激光并观察它们的角度。最后,我想看看这些角度的分布,并输出其中三个的样本。

为了检测图像中的线条,我查看了以下各种组合:

  • Hough Lines
  • Canny边缘检测
  • 双边/高斯过滤
  • 去噪
  • 直方图均衡
  • 形态转换
  • 阈值

我已经尝试了很多不同方法的组合,我似乎无法想出任何真正有用的东西。我一直在尝试的是:

import cv2
import numpy as np

img = cv2.imread('testimg.jpg')
grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
equal = clahe.apply(grey)

denoise = cv2.fastNlMeansDenoising(equal, 10, 10, 7, 21)

blurred = cv2.GaussianBlur(denoise, (3, 3), 0)
blurred = cv2.medianBlur(blurred, 9)

(mu, sigma) = cv2.meanStdDev(blurred)
edge = cv2.Canny(blurred, mu - sigma, mu + sigma)

lines = cv2.HoughLines(edge, 1, np.pi/180, 50)

if lines is not None:
    print len(lines[0])

    for rho,theta in lines[0]:
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))
        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))

        cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)

cv2.imshow("preview", img)
cv2.waitKey(0)

这只是众多不同尝试之一。即使我能找到一种对其中一张图像效果稍好的方法,但事实证明对另一张图像来说情况要差得多。我并不期待完全完美的结果,但我确信它们可能比我迄今为止所做的更好!

有人能提出一个帮助我前进的策略吗?

1 个答案:

答案 0 :(得分:0)

这是一个答案。如果您的相机处于固定位置,那么这个答案可以帮助您,激光器也是如此......您的激光器可以从您可以确定的坐标发出。因此,如果您有许多实验同时使用相同的设置,这可能是一个起点。

问题image information along a polar coordinate system有助于获得极地变换。我选择不使用openCV,因为不是每个人都可以使用openCV(windows)。我从链接的问题中获取了代码,然后玩了一下。如果你将他的代码添加到我的(没有import或main方法),那么你将拥有所需的功能。

import numpy as np
import scipy as sp
import scipy.ndimage

import matplotlib.pyplot as plt
import sys

import Image

def main():

    data = np.array(Image.open('crop1.jpg').convert('LA').convert('RGB'))

    origin = (188, -30)
    polar_grid, r, theta = reproject_image_into_polar(data, origin=origin)

    means, angs = mean_move(polar_grid, 10, 5)
    means = np.array(means)
    means -= np.mean(means)
    means[means<0] = 0
    means *= means

    plt.figure()
    plt.bar(angs, means)
    plt.show()

def mean_move(data, width, stride):
  means = []
  angs = []
  x = 0
  while True:
    if x + width > data.shape[1]:
      break
    d = data[:,x:x+width]
    m =  np.mean(d[d!=0])
    means.append(m)
    ang = 180./data.shape[1] * float(x + x+width)/2.
    angs.append(ang)
    x += stride

  return means, angs

# copy-paste Joe Kington code here

上部源周围的图像。

cropped image here

请注意,我选择了一个激光并在其源周围裁剪了一个区域。这可以自动完成并重复每个图像。我还根据我认为发射的位置估计了源坐标(188,-30)(x,y形式)。下面的图像(一个gimp屏幕截图!)显示了我的推理(似乎有一条非常微弱的光线,我也追溯到了这个交点)......它还显示了角度~140度的测量值。

enter image description here

图像的极坐标变换(注意垂直带强度...它是垂直的,因为我们为激光选择了正确的原点)

polar transform of image

使用非常匆忙创建的移动窗口意味着函数和粗略映射到度数角度,以及来自均值+归零+平方的差异。

enter image description here

所以你的任务就是抓住这些高峰。哦~~ 140!谁是你的爸爸!

总结一下,如果设置已修复,那么这可能对您有所帮助!我真的需要回去工作并停止拖延。