C++ opencv 截取任意形状封闭图形

C++ opencv 截取任意形状封闭图形

漫水填充加模板实现截图。
**实现思路:**创建一个原图大小相同的单通道白色模板,在原图上通过鼠标圈出抠图区域,
并在模板上相同区域使用黑色线条画出对应区域,再将模板进行漫水填充,模板所选区域外全为黑色,区域内为白色。最后,使用copyTo()将模板上不为0的区域像素拷贝出来。

//FloodFill漫水函数原型
int floodFill(InputOutputArray image, InputOutputArray mask,
 Point seedPoint, Scalar newVal, Rect* rect=0,
  Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 );
  InputOutputArray:输入和输出图像。
  mask:            输入的掩码图像。
  seedPoint:      进行填充的起始点。 
  newVal:         图像中所有被算法选中的点,都用这个数值来填充。
       rect:            最小包围矩阵。
  loDiff:         最大的低亮度之间的差异。
       upDiff:         最大的高亮度之间的差异。
  flag:           选择算法连接方式。
//		copyTo函数
src.copyTo(dst, mask); 
src拷贝原图,dst结果图,mask模板。
mask不存在时将src拷贝给dst,存在时将mask像素不为0的区域拷贝给dst。
Mat dst = src;浅复制,共享同一块内存;copyto深复制,各自拥有内存。
//初始化及回调函数的调用
	bool g_bDrawingBox = false;//记录鼠标左键是否按下
	Rect g_rectangle;			//画矩形所用rect
	Point2i roi_p;//路径上的点	//画任意线条

    image_mask.create(roi_image1.rows, roi_image1.cols, CV_8U);
    image_mask.setTo(Scalar(255));
    setMouseCallback("裁剪图", mouse, (void*)&roi_image1);
    while (1)
    {
        if (waitKey(10) == 27) { break; }//esc键,程序退出
        imshow("裁剪图", roi_image1);

    }

//回调函数

void mouse(int event, int x, int y, int flags, void* param) {
    Mat& image = *(Mat*)param;
    switch (event){
    case EVENT_LBUTTONDOWN: {
        cout << "EVENT_LBUTTONDOWN" << endl;
        g_bDrawingBox = true;
        g_rectangle = Rect(x, y, 0, 0);
        roi_p.x = x;
        roi_p.y = y;
    }
         break;
    case EVENT_MOUSEMOVE: {
        if (g_bDrawingBox) {
            g_rectangle.width = x - g_rectangle.x;
            g_rectangle.height = y - g_rectangle.y;
            line(image, roi_p, Point2i(x,y), Scalar(0, 0, 255), 1, CV_AA);
            line(image_mask, roi_p, Point2i(x, y), Scalar(0), 3, 8);
            roi_p.x = x;
            roi_p.y = y;
        }
    }
        break;
    case EVENT_LBUTTONUP: {
    	//	可以将起点和终点的矩形画出来
        cout << "EVENT_LBUTTONUP" << endl;
        g_bDrawingBox = false;
        if (g_rectangle.width < 0) {
            g_rectangle.x += g_rectangle.width;
            g_rectangle.width *= -1;
        }
        if (g_rectangle.height < 0) {
            g_rectangle.y += g_rectangle.height;
            g_rectangle.height *= -1;
        }
        rectangle(image, g_rectangle, Scalar(0, 0, 255));
    }
        break;
    case EVENT_RBUTTONUP: {
        floodFill(image_mask, Point(100, 100), Scalar(0, 0, 0));//漫水填充
        image.copyTo(dst, image_mask);//抠图
    }
    }
}

你可能感兴趣的:(opencv,c++,计算机视觉)