Mục tiêu của tôi là chạy mô hình TensorFlow trong thời gian thực để điều khiển xe từ mô hình đã học. Hệ thống xe của chúng tôi sử dụng ROS (Hệ điều hành Robot) được gắn chặt với OpenCV. Vì vậy, tôi nhận được một OpenCV Mat chứa hình ảnh quan tâm từ ROS.Nhập OpenCV Mat vào C++ Tensorflow mà không cần sao chép
cv::Mat cameraImg;
Tôi muốn tạo Tensorflow Tensor trực tiếp từ dữ liệu trong ma trận OpenCV này để tránh chi phí sao chép ma trận từng dòng một. Sử dụng câu trả lời cho This Question tôi đã được quản lý để có được những đường chuyền về phía trước của mạng lưới làm việc với đoạn mã sau:
cameraImg.convertTo(cameraImg, CV_32FC3);
Tensor inputImg(DT_FLOAT, TensorShape({1,inputheight,inputwidth,3}));
auto inputImageMapped = inputImg.tensor<float, 4>();
auto start = std::chrono::system_clock::now();
//Copy all the data over
for (int y = 0; y < inputheight; ++y) {
const float* source_row = ((float*)cameraImg.data) + (y * inputwidth * 3);
for (int x = 0; x < inputwidth; ++x) {
const float* source_pixel = source_row + (x * 3);
inputImageMapped(0, y, x, 0) = source_pixel[2];
inputImageMapped(0, y, x, 1) = source_pixel[1];
inputImageMapped(0, y, x, 2) = source_pixel[0];
}
}
auto end = std::chrono::system_clock::now();
Tuy nhiên, sử dụng phương pháp này, các bản sao cho tensor mất khoảng 80ms và 130ms, trong khi toàn bộ đường chuyền về phía trước (đối với mạng chuyển tiếp 10 lớp) chỉ mất 25ms.
Nhìn vào the tensorflow documentation, có vẻ như có một hàm tạo Tensor có trình phân bổ. Tuy nhiên, tôi không thể tìm thấy bất kỳ tài liệu Tensorflow hoặc Eigen nào liên quan đến chức năng này hoặc Eigen Map class vì nó liên quan đến Tensors.
Có ai có thông tin chi tiết về cách mã này có thể được tăng tốc hay không, lý tưởng nhất là sử dụng lại bộ nhớ OpenCV của tôi?
EDIT: Tôi đã triển khai thành công những gì @mrry đề xuất và có thể sử dụng lại bộ nhớ do OpenCV cấp. Tôi đã mở github issue 8033 yêu cầu điều này được thêm vào cây nguồn tensorflow. Phương pháp của tôi không đẹp, nhưng nó hoạt động.
Vẫn còn rất khó để biên dịch một thư viện bên ngoài và liên kết nó với thư viện libtensorflow.so. Có khả năng tensorflow cmake library sẽ giúp ích cho điều này, tôi chưa thử.
Awesome, cảm ơn cho phản ứng nhanh chóng! Tôi sẽ cố gắng sử dụng C api để có được một tensor vào mã của tôi. Tôi sử dụng api C++ hiện tại để tải đồ thị của tôi từ đĩa, vì vậy tôi đoán tôi sẽ phải cố gắng sử dụng API bạn bè riêng. Tôi sẽ cho bạn biết ngay sau khi tôi có thể nhận được kết quả. – Paul
Tôi đang cố gắng để có được điều này để làm việc với thư viện bên ngoài của tôi nhưng không có may mắn biên dịch nó. Tôi có thể làm cho trình biên dịch hài lòng bằng cách khai báo lớp TensorCApi và lớp TF_Tensor trong nguồn của tôi.Tuy nhiên, khi tôi chạy nó, tôi nhận được một lỗi: '/ opt/ros/indigo/lib/nodelet/nodelet: lỗi tra cứu ký hiệu: /home/paul/catkin_ws/devel/lib//libDeepModel.so: biểu tượng không xác định: TF_NewTensor '. Khi tôi cố định nghĩa lớp trong nguồn tensorflow (trong 'c_api.h'), có vẻ như nó không được biên dịch. Tôi đang sử dụng mục tiêu xây dựng '// tensorflow: libtensorflow.so', mục tiêu xây dựng này không bao gồm api C? – Paul
Bạn đã bao giờ làm việc này chưa? Nếu vậy, bạn có bất kỳ đoạn mã nào mà bạn có thể chia sẻ không? Tôi cũng đang tìm cách để giao tiếp opencv từ ROS và cần một cái gì đó như thế này. Tôi đã rất ngạc nhiên khi tôi bắt đầu nhìn vào điều này rằng cách duy nhất để có được một opencv Mat thành một Tensor là một vòng lặp sao chép khủng khiếp chậm. – dcofer