之前,我们每次使用形态学操作,需要设置核,核的大小需要我们自己设置,每次想要调整,都是需要不断停止运行,修改代码,然后再执行,这样太慢了,我们能不能运行的过程中,通过调整滑动条,让它自动调整核的大小呢?
opencv提供了trackbar功能。我们可以创建一个trackbar来动态调整核的大小,这样,我们就不用每次都重新修改代码,重新编译了。
创建trackbar的API是
createTrackbar()
int createTrackbar(
const String& trackbarname,
const String& winname,
int* value,
int count,
TrackbarCallback onChange = 0,
void* userdata = 0
);
(1)String类型的trackbarname,滑动条轨迹名。
(2)string类型的winname,用作创建的轨迹栏父窗口的名称。即滑动条依附的窗口名。
(3)int类型的指针value,指向整数变量的可选指针,其值反映滑块的位置。创建时,滑块位置由该变量定义,滑块初始位置就是这个变量当前的值。
(4)int类型的count,滑块的最大位置。最小位置总是0。
(5)TrackbarCallback类型的onChange:指向每次滑块更改位置时要调用的函数的指针。此函数的原型应为
void Foo(int,void\*);
其中第一个参数是trackbar位置,第二个参数是用户数据(请参阅下一个参数)。如果回调是空指针,则不调用回调,但只更新值。
(6)void类型的userdata:按原样传递给回调的用户数据,默认为0。它可以用来处理trackbar事件而不使用全局变量。如果第三个值为全局变量,忽略这个值。
#include
#include
using namespace std;
using namespace cv;
Mat src, dst;
char inimg[] = "【inputImage】";
char outimg[] = "【outputImage】";
void changeTrackbar(int pos, void*usrdata) {
Mat kernel = getStructuringElement(MORPH_RECT, Size(2 * pos + 1, 2 * pos + 1), Point(-1, -1));
morphologyEx(src, dst, 0, kernel);
imshow(outimg, dst);
}
int main()
{
src = imread("C:/Users/86176/Pictures/pics/shape1.png");
if (!src.data)
{
cout << "could not load image !";
return -1;
}
namedWindow(inimg, CV_WINDOW_AUTOSIZE);
namedWindow(outimg, CV_WINDOW_AUTOSIZE);
imshow(inimg, src);
int initValue = 2;
int maxSize = 10;
createTrackbar("kernel", outimg, &initValue, maxSize, changeTrackbar);
waitKey(0);
return 0;
}
原图如上
pos = 1
kernel = 1 x 2 + 1 = 3
pos = 10
kernel = 10 x 2 + 1 =21
我们通过设置。滑动条,还可以调整形态学操作的类型。
大家应该还记得形态学操作类型会对应到不同的数字:
enum MorphTypes{
MORPH_ERODE = 0, //腐蚀
MORPH_DILATE = 1, //膨胀
MORPH_OPEN = 2, //开操作
MORPH_CLOSE = 3, //闭操作
MORPH_GRADIENT = 4, //梯度操作
MORPH_TOPHAT = 5, //顶帽操作
MORPH_BLACKHAT = 6, //黑帽操作
};
所以我们可以通过滑动条来控制不同的类型。这次滑动条的最大值为6。