2015-08-21 27 views
5

Tôi đã phát hiện các cạnh của sóng nước bằng cách sử dụng phát hiện cạnh khó chịu. Tuy nhiên, tôi muốn phù hợp với một đường cong cho cạnh này. Điều đó có thể xảy ra trong OpenCV không?OpenCV: phù hợp với các cạnh được phát hiện

Dưới đây là hình ảnh trước khi phát hiện cạnh: Image before edge detection.

Dưới đây là kết quả của các hoạt động phát hiện cạnh: Result after detecting

Mã này đã được sao chép từ một ví dụ trong các hướng dẫn OpenCV:

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() 

Trả lời

6

Sóng khá đơn giản, vì vậy chúng tôi sẽ vừa với đường cong đa thức đến cạnh chính được xác định bởi đầu ra của cv2. Trước tiên, chúng tôi muốn lấy các điểm của cạnh chính. Giả sử nguồn gốc của bạn giống như hình ảnh, ở trên cùng bên trái. Nhìn vào hình ảnh ban đầu, tôi nghĩ rằng chúng tôi sẽ có một xấp xỉ tốt cho các điểm quan tâm của chúng tôi nếu chúng ta chỉ lấy các điểm có số lớn nhất là y trong phạm vi (750, 1500).

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] 

Nếu chúng tôi vẽ đồ thị những điểm này, chúng ta có thể thấy chúng rất gần với những điểm chúng tôi hướng đến.

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() 

extracted points

Và bây giờ mà chúng tôi đã có một loạt các cặp toạ độ chúng ta có thể sử dụng numpy.polyfit để tạo ra các hệ số cho một đa thức phù hợp nhất, và numpy.poly1d để tạo ra các chức năng từ những hệ số.

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

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

và sau đó âm mưu xác minh

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

Sẽ không phải là hàm lượng giác được tự nhiên hơn để mô hình hóa một làn sóng? Hình dạng trong biểu hiện hình sin. –

+0

Tôi sẽ thử! Suy nghĩ của tôi là một đa thức có thể hoạt động tốt hơn ở đây vì nó có thể phù hợp với các khu vực nông hơn ở bên trái và bên phải chặt chẽ hơn. Không phải của tôi, nhưng việc lọc và/hoặc loại bỏ một số điểm có thể tạo ra kết quả tốt hơn. –

+0

Cảm ơn Chris, đây là tất cả những gì tôi muốn. Xin lỗi vì tôi đã thấy điều này muộn một chút. Nó hoạt động trên máy tính xách tay của tôi, tuy nhiên tôi không thể làm cho nó hoạt động trên Raspberry Pi 2 của tôi bởi vì tôi không thể tìm thấy một cách để cài đặt 'numba'. Bất kỳ đề xuất? – VaFancy

Các vấn đề liên quan