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