Phương pháp nhanh nhất đáng tin cậy nhất để phát hiện một đường laser đỏ nằm ngang trong một hình ảnh bằng cách sử dụng Python là gì? Tôi đang nghiên cứu một dự án nhỏ liên quan đến quét laser 3D và tôi cần có khả năng phát hiện tia laser trong một hình ảnh để tính khoảng cách từ sự biến dạng của nó.Làm thế nào để phát hiện một đường laser trong một hình ảnh bằng cách sử dụng Python
Để bắt đầu, tôi có hai hình ảnh, một hình ảnh tham chiếu A được biết là không chứa đường laser, và hình ảnh B chắc chắn chứa đường laser, có thể bị méo. ví dụ.
Ảnh mẫu A:
Ảnh mẫu B:
Kể từ đây là những RGB, nhưng laser màu đỏ, tôi loại bỏ một số tiếng ồn bằng cách tách ra khỏi màu xanh và các kênh màu xanh lục sử dụng chức năng này:
from PIL import Image
import numpy as np
def only_red(im):
"""
Strips out everything except red.
"""
data = np.array(im)
red, green, blue, alpha = data.T
im2 = Image.fromarray(red.T)
return im2
Đó được tôi những hình ảnh này:
Tiếp theo, tôi cố gắng và loại bỏ tiếng ồn hơn bằng cách lấy sự khác biệt của hai hình ảnh này sử dụng PIL.ImageChops.difference()
. Lý tưởng nhất, sự tiếp xúc giữa hai hình ảnh sẽ giống hệt nhau, gây ra sự khác biệt không chứa gì ngoại trừ dòng laser. Thật không may, bởi vì laser thêm ánh sáng, độ phơi sáng và độ sáng tổng thể của mỗi ảnh là khác nhau đáng kể, dẫn đến sự khác biệt mà vẫn có tiếng ồn đáng kể. ví dụ.
bước cuối cùng của tôi là để thực hiện một "đoán tốt nhất" như là nơi dòng là. Vì tôi biết đường thẳng sẽ nằm ngang và đường laser nên là thứ sáng nhất trong hình ảnh, tôi quét từng cột và tìm hàng có pixel sáng nhất mà tôi cho là đường laser. Mã cho điều này là:
import os
from PIL import Image, ImageOps
import numpy as np
x = Image.open('laser-diff.png', 'r')
x = x.convert('L')
out = Image.new("L", x.size, "black")
pix = out.load()
y = np.asarray(x.getdata(), dtype=np.float64).reshape((x.size[1], x.size[0]))
print y.shape
for col_i in xrange(y.shape[1]):
col_max = max([(y[row_i][col_i], row_i) for row_i in xrange(y.shape[0])])
col_max_brightness, col_max_row = col_max
print col_i, col_max
pix[col_i, col_max_row] = 255
out.save('laser-line.png')
Tất cả tôi thực sự cần phải thực hiện tính toán khoảng cách của tôi là mảng col_max
giá trị, nhưng laser-line.png
giúp tôi hình dung sự thành công, và trông giống như:
Như bạn có thể thấy, ước tính là khá gần, nhưng nó vẫn có một số tiếng ồn, chủ yếu là ở phía bên trái của hình ảnh, nơi dòng laser được hấp thụ bởi một kết thúc màu đen mờ.
Tôi có thể làm gì để cải thiện độ chính xác và/hoặc tốc độ của mình? Tôi đang cố gắng để chạy điều này trên một nền tảng ARM như Raspberry Pi, vì vậy tôi lo lắng mã của tôi có thể là quá kém hiệu quả để chạy tốt.
Tôi không hoàn toàn quen thuộc với các chức năng ma trận của Numpy, vì vậy tôi phải giải quyết cho một vòng lặp chậm để quét từng cột thay vì một cái gì đó hiệu quả hơn. Có cách nào nhanh chóng để tìm hàng có pixel sáng nhất trên mỗi cột trong Numpy không?
Ngoài ra, có cách nào đáng tin cậy để cân bằng hình ảnh trước khi thực hiện sự khác biệt mà không làm mờ đường laser không?
có thể cuối cùng, bạn có thể xóa tất cả các điểm có toạ độ y không nằm trong định vị 25% ~ 75%. Sau đó, bạn có thể nhận được kết quả tốt hơn, sau đó điền vào các giá trị bị thiếu bằng cách sử dụng locf..etc –
@ B.Mr.W., Bạn đã đúng một phần. Vì laser được lắp bên dưới máy ảnh và song song với mặt phẳng tiêu cự của nó, tất cả các điểm laser phải nằm dưới hàng giữa, nghĩa là tất cả các điểm trên đều là tiếng ồn. Cảm ơn. – Cerin