TrackbarCallback 回调函数必须为 void(int,void*),如果你用了传其它参数的函数,对不起,报错与cv::TrackbarCallback类型的形参不兼容。
同时,这也代表里面用的参数可能得设置成全局变量了,虽然有时候设置过多的全局变量回很复杂,但这里似乎不可避免,首先这里的参数肯定有需要改变的,不能用define,不然你也没必要使用trackbar,其次就是上面说的,会调函数不能传参,也就是每次修改以后,不能通过传参让回调函数知道”这个参数已经被改变了,重新给我算一次“。----------------------------------------反省的分割线---------------------------------------------------------------------------
之前对TrackbarCallback 理解的不够深入,上面所说的代码风格的缺陷实际上是有办法解决的。
解决办法是引入一个指针,这个指针可以指向一个结构体,而结构体里定义了一系列需要用到的变量。具体如以下代码//要引入 improc.hppstruct ED_DATA{ Mat src' Mat dst; int elem; int size; ED_DATA(Mat &s,int e_elem = 0,int e_size = 0):src(s),elem(e_elem),size(e_size){}};void Dilation_size(int bar_val,void* data){ ED_DATA dl_data = *(ED_DATA*)data; int dilation_type; if(dl_data.elem ==0){ dilation_type == MORPH_RECT;} if(dl_data.elem ==1){ dilation_type == MORPH_CROSS;} if(dl_data.elem ==2){ dilation_type == MORPH_ELLIPSE;} Mat element = getStructuringElement(dilation_type,Size(2*bar_val+1,2*bar_val+1),Point(bar_val,bar_val)); erode(dl_data.src,dl_data.dst,element);}
这样,bar_val就成了最后要滑动的变化值,而void型指针data被初始化为了ED_DATA型的指针后,也拥有了需要改变的其它变量,例如这里dilation type,它可以决定用什么样的元素取腐蚀。
在createTrackbar中,要将一个变量的地址传给 int *value,同时也要传入数据结构data 也就是定义的结构体,函数内部会又自动传给上述函数