2012-06-14 41 views
7

Tôi đang phát triển các ứng dụng xử lý độ sâu (Xbox Kinect, Asus Xtion, v.v.) bằng cách sử dụng OpenNI.C# hiển thị pixel nhanh

Tôi cần một cách vẽ thực sự đơn giản và nhanh chóng trên biểu mẫu Windows khi dữ liệu độ sâu mới có sẵn từ cảm biến (30 hoặc 60 khung hình/giây tùy thuộc vào độ phân giải).

Hiện tại tôi đang làm mất hiệu lực bảng đệm đôi từ một chuỗi riêng biệt khi dữ liệu có sẵn và sau đó đặt pixel của bitmap trong phương pháp vẽ của bảng điều khiển, cho năng suất 5fps khủng khiếp.

System.Drawing.Graphics dường như thiếu một cách nhanh chóng để đặt từng pixel riêng lẻ, trừ khi có ai đó có thể hướng dẫn cách khác.

Tôi chỉ cần đặt màu pixel, vì vậy, bạn muốn tránh sử dụng API hiển thị tốc độ cao của bên thứ ba nếu có thể và sử dụng lý tưởng một thứ gì đó có nguồn gốc càng tốt.

Có ai có bất kỳ đề xuất nào không?

+0

Bạn đang đặt các pixel hiện tại như thế nào? – leppie

+0

Đã tạo bitmap, sử dụng image.SetPixel (x, y, màu). Sau khi tất cả, gọi graphics.drawImage (hình ảnh, vv) –

+2

'SetPixel' là rất chậm. Nhìn vào phương pháp 'Scanline'. – leppie

Trả lời

4

Nếu bạn đang sử dụng Bitmap, bạn nên sử dụng LockBits và UnlockBits để truy cập dữ liệu trực tiếp trong bộ nhớ. Trong C#, bạn có thể nhận được một số hiệu suất bổ sung bằng cách sử dụng các khối mã không an toàn và các con trỏ.

Xem liên kết này để biết thêm thông tin: http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx

+0

Đây là một cải tiến mạnh mẽ. Tôi không thể đạt được nhiều hơn 10 khung hình/giây khi vẽ một bitmap 640x480 trống để kết luận là System.Drawing về cơ bản không nhanh. Giải pháp này, kết hợp với thu nhỏ hình ảnh xuống và chỉ hiển thị một số pixel để đạt được FPS yêu cầu là câu trả lời. –

4

image.SetPixel() rất chậm khi bạn thay thế nhiều pixel cho mỗi khung và bạn cần nhiều khung hình mỗi giây.

Nó sẽ nhanh hơn rất nhiều khi bạn sử dụng một WriteableBitmap và gọi CopyPixels

Bằng cách này bạn có thể điền vào các mảng với dữ liệu pixel sử dụng nhiều chủ đề và chỉ cần blit mảng đến hình ảnh trong một cuộc gọi duy nhất.

EDIT

Lưu ý rằng WriteableBitmap là một lớp WPF. Nếu bạn bị ràng buộc với WinForms, bạn có thể cần phải tạo việc triển khai của riêng bạn. WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?

+0

Cảm ơn bạn đã trả lời, nhưng liên kết câu trả lời bạn đã cung cấp sử dụng .SetPixel() trong chuyển đổi từ WriteableBitmap thành System.Drawing.Image. –

+0

Có, và đó là khủng khiếp cho tốc độ. Một cách khác là ghi vào một mảng và sử dụng bộ mã hóa (PNG, BMP, ...) để biến nó thành một hình ảnh hiển thị nó. Vấn đề chính với SetPixel là nó đặt một pixel đơn lẻ. –

0

Bạn có thể thử tôi LINQ image processing library để làm việc với bạn "đệm-bitmap". Nó sử dụng một cú pháp rất dễ tiếp cận nhưng rất hiệu quả cho các bitmap lớn. Nó có sẵn trên Nuget dưới dạng một tệp duy nhất bao gồm trong dự án của bạn.

Hy vọng điều đó sẽ hữu ích!

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