我正在尝试使用C ++ Actor Framework和OpenCV制作分布式视觉系统。我开始使用概念验证代码编译,但是在运行" edge"窗口已创建,但不显示任何内容(以下显示的代码)。
我真的不明白为什么它不起作用,任何帮助都会受到赞赏。
提前致谢。
PS代码
的main.cpp
#include <vector>
#include "opencv2/opencv.hpp"
#include "caf/all.hpp"
using namespace cv;
using namespace caf;
using namespace std;
struct Image {
Image(Mat mat = Mat()) {
data.assign(mat.datastart,mat.dataend);
type = mat.type();
rows = mat.rows;
cols = mat.cols;
}
Mat toMat() const {
return Mat(rows,cols,type,(void *)data.data());
}
vector<uchar> data;
int type;
int rows;
int cols;
};
bool operator==(const Image& lhs, const Image& rhs) {
return lhs.data == rhs.data
&& lhs.type == rhs.type
&& lhs.rows == rhs.rows
&& lhs.cols == rhs.cols;
}
class VideoCaptureActor : public event_based_actor{
VideoCapture cap;
actor buddy;
protected:
behavior make_behavior() override {
send(this,get_atom::value);
return {
[=](get_atom){
while(true){
Mat frame;
cap >> frame;
this->send(buddy,put_atom::value,Image(frame));
if(waitKey(60) >= 0){
send(this,ok_atom::value);
break;
}
}
},
[=](ok_atom){
cout << "Hello "<< buddy.id() <<" !"<<endl;
},
others >> [=](){
cerr << "unexpected: " << to_string(this->current_message()) << buddy.id() << endl;
}
};
}
public:
VideoCaptureActor(const actor &buddy){
this->buddy = buddy;
cap.open(0);
if(!cap.isOpened())
throw -1;
}
};
class CannyActor : public event_based_actor {
Mat edges;
protected:
behavior make_behavior() override {
return {
[=](put_atom,Image image){
cvtColor(image.toMat(), edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
},
others >> [=] {
cerr << "unexpected: " << to_string(this->current_message()) << endl;
}
};
}
public:
CannyActor(){
namedWindow("edges",1);
}
};
int main(int, char**) {
announce<Image>("Image",&Image::data,&Image::type,&Image::rows,&Image::cols);
try {
spawn<VideoCaptureActor>(spawn<CannyActor>());
}catch(int x){
cerr<<x<<endl;
}
await_all_actors_done();
shutdown();
return 0;
}
的CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
project(SmartVision CXX)
set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
find_package(OpenCV REQUIRED)
find_package(Libcaf COMPONENTS core io REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wextra -Wall -pedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_RELEASE "-O4")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
include_directories(${OpenCV_INCLUDE_DIRS} ${LIBCAF_INCLUDE_DIRS})
set(SOURCE_FILES main.cpp)
add_executable(SmartVision ${SOURCE_FILES})
target_link_libraries(SmartVision ${OpenCV_LIBS} ${LIBCAF_LIBRARIES})
我还将FindLibcaf.cmake文件放在我的项目根文件夹中,以便让cmake找到CAF库
我使用MacOS X Yosemite和CLion 1.0.2作为IDE 运行程序时使用了大量的CPU资源:我第一次听到macbook的粉丝! CAF应该是一个轻量级框架,但也许我以错误的方式使用它。
答案 0 :(得分:1)
免责声明:我没有使用OpenCV的经验。所以我只能帮助弄清楚CAF方面发生了什么。
演员应该是异步的,非阻塞的和合作的。 while (true)
中的VideoCaptureActor
循环阻止CAF调度程序中的工作线程。每次在不同的线程中调用imshow
是否安全?因为这最终可能会发生在CannyActor
。因此,它可能只是归结为OpenCV中的线程问题。
我建议做的第一件事是:
spawn<VideoCaptureActor, detached>(spawn<CannyActor, detached>());
这将为你的两个演员分配一个专用线程。
只要您不是通过网络发送图片,现在直接发送Mat
(而不是宣布它)是安全的,看看是否使用{{来回转换1}}打破了一些东西。您还可以在将来的某个时间编写自定义序列化程序,以便直接序列化/反序列化Image
。
Mat
如果[=](get_atom) {
while (true) {
Mat frame;
cap >> frame;
send(buddy, put_atom::value, std::move(frame));
if(waitKey(60) >= 0){
send(this, ok_atom::value);
break;
}
}
},
没有移动构造函数,您可以将框架存储在Mat
或类似的东西中以完全摆脱额外的副本(在额外的堆分配+间接的扩展中) )。
我希望有所帮助。