2015-08-21 22 views
5

Kanatlı kenar algılamayı kullanarak bir su dalgasının kenarlarını tespit ettim. Bununla birlikte, bu kenar için bir eğri uydurmak istiyorum. OpenCV'de bu mümkün mü? Burada Image before edge detection.OpenCV: algılanan kenarları sığdır

kenar algılama işleminin sonucudur: Burada

kenar algılama önce görüntü kod OpenCV dökümanında örnek kopyalanmıştır Result after detecting

:

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 

img = cv2.imread('BW.JPG',0) 
edges = cv2.Canny(img,100,200) 

plt.plot(1),plt.imshow(edges,cmap = 'gray') 
plt.title('WAVE') 
plt.show() 

cevap

6

Dalga oldukça basit, bu nedenle cv2 çıktısı tarafından tanımlanan birincil kenarına bir polinom eğrisi sığdıracağız. İlk olarak, numaralı puanlarını birincil kenardan almak istiyoruz. Kökeninizin resmin üstünde, sol üstte olduğu gibi olduğunu varsayalım. Orijinal görüntüye baktığımızda, en büyük y (750, 1500) aralığında puan alırsak, ilgi alanlarımız için iyi bir yaklaşıma sahip olacağımızı düşünüyorum.

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 
from numba import jit 

# Show plot 
img = cv2.imread('wave.jpg',0) 
edges = cv2.Canny(img,100,200) 

# http://stackoverflow.com/a/29799815/1698058 
# Get index of matching value. 
@jit(nopython=True) 
def find_first(item, vec): 
    """return the index of the first occurence of item in vec""" 
    for i in range(len(vec)): 
     if item == vec[i]: 
      return i 
    return -1 

bounds = [750, 1500] 
# Now the points we want are the lowest-index 255 in each row 
window = edges[bounds[1]:bounds[0]:-1].transpose() 

xy = [] 
for i in range(len(window)): 
    col = window[i] 
    j = find_first(255, col) 
    if j != -1: 
     xy.extend((i, j)) 
# Reshape into [[x1, y1],...] 
data = np.array(xy).reshape((-1, 2)) 
# Translate points back to original positions. 
data[:, 1] = bounds[1] - data[:, 1] 

Bu noktaları çizersek, hedeflediklerimize çok yakın olduklarını görebiliriz.

extracted points

plt.figure(1, figsize=(8, 16)) 
ax1 = plt.subplot(211) 
ax1.imshow(edges,cmap = 'gray') 
ax2 = plt.subplot(212) 
ax2.axis([0, edges.shape[1], edges.shape[0], 0]) 
ax2.plot(data[:,1]) 
plt.show() 
Ve şimdi koordinat çiftleri bir dizi biz en uygun polinomun katsayıları üretmek için numpy.polyfit kullanabilir ve numpy.poly1d bu katsayılar gelen işlevi oluşturmak için var olduğunu.

xdata = data[:,0] 
ydata = data[:,1] 

z = np.polyfit(xdata, ydata, 5) 
f = np.poly1d(z) 

ve sonra arsa

t = np.arange(0, edges.shape[1], 1) 
plt.figure(2, figsize=(8, 16)) 
ax1 = plt.subplot(211) 
ax1.imshow(edges,cmap = 'gray') 
ax2 = plt.subplot(212) 
ax2.axis([0, edges.shape[1], edges.shape[0], 0]) 
ax2.plot(t, f(t)) 
plt.show() 

showing curve

+0

bir trigonometrik fonksiyon bir dalga modelleme için daha doğal olmaz doğrulamak için? Açıkça sinüzoidal şekil. –

+0

Denerim! Benim düşüncem, bir polinomun burada daha iyi çalışabilmesiydi, çünkü uzak ve sağdaki daha sığ alanlara daha yakın bir şekilde sığabiliyordu. Benimki yok, ama bazı noktaları filtrelemek ve/veya atmak daha iyi bir sonuç doğurabilir. –

+0

Teşekkürler Chris, istediğim bu. Üzgünüm, bunu biraz gecikmiş gördüm. Dizüstü bilgisayarımda çalışıyor, ancak Raspberry Pi 2 cihazımda çalışamıyorum çünkü 'numba' yüklemek için bir yol bulamıyorum. Baska öneri? – VaFancy