opencv 图像分割,掩码分割,对象分割,grabCut图割算法

本章内容


     1. 鼠标时间捕获
     2. grabCut图割算法

 

opencv 图像分割,掩码分割,对象分割,grabCut图割算法

输出结果

opencv 图像分割,掩码分割,对象分割,grabCut图割算法

源码


#include<opencv2/opencv.hpp>
#include<iostream>

void showImage();
void getGrabCut();
void onMouse(int event, int x, int y, int flags, void* param); // 鼠标事件响应槽函数
cv::String winTitle = "input Image";
cv::Rect rect;
cv::Mat src;
cv::Mat mask, bgModel, fgModel;

int main(int argc, char** argv) {
    /* 本章内容
     1. 鼠标时间捕获

    */

    cv::String fileName = "/home/wang/dev/Image/mv.jpeg";
    src = cv::imread(fileName);
    if(src.data == NULL ){
        std::cout << "文件读入失败" << std::endl;
        return -1;
    }
   // 初始化图割相关参数
    mask = cv::Mat::zeros(src.size(),CV_8UC1);
    cv::imshow(winTitle, src);
    int key;
    while(1){
        key = cv::waitKey(20);
        if(('q' == key)||('Q' == key)){
                std::cout << "退出系统" << std::endl;
                break;
        }
        cv::setMouseCallback(winTitle,onMouse);
    }
    return 0;
}
void showImage() {
    cv::Mat result;
    result = src.clone();
    cv::rectangle(result,rect,cv::Scalar(0,0,255),2);
    cv::imshow(winTitle, result);
}

void onMouse(int event, int x, int y, int flags, void* param){
    switch(event){
        case cv::EVENT_LBUTTONDOWN:
        // 当鼠标事件按下时,设计矩形框的起始位置
        std::cout << "鼠标左键按下" << std::endl;
        rect.x = x;
        rect.y = y;
        rect.width = 1;
        rect.height = 1;
        break;
    case cv::EVENT_MOUSEMOVE:
        // 鼠标时间移动时,设置矩形框的宽度和高度
//        std::cout << "鼠标移动 flags = "  << flags << std::endl;
        if(flags&cv::EVENT_LBUTTONDOWN){
            rect = cv::Rect(cv::Point(rect.x, rect.y), cv::Point(x, y));
            showImage();
        }
        break;
    case cv::EVENT_LBUTTONUP: // falgs 鼠标按下移动为33,抬起移动为32
        // 绘制矩形框
        /*图割算法
            api接口:CV_EXPORTS_W void grabCut( InputArray img, InputOutputArray mask, Rect rect,
                                       InputOutputArray bgdModel, InputOutputArray fgdModel,
                                       int iterCount, int mode = GC_EVAL );
        */

        if ((rect.width > 2) && (rect.height > 2)) {
            cv::grabCut(src,mask,rect,bgModel,fgModel,10);
            cv::grabCut(src,mask,rect,bgModel,fgModel,10,cv::GC_INIT_WITH_RECT);
            cv::Mat result = cv::Mat::zeros(src.size(), CV_8UC3);
            for(int i=0; i<src.rows;i++){
                for(int j=0; j<src.cols;j++){
                    if(mask.at<uchar>(i,j)>2){
                        result.at<cv::Vec3b>(i,j) = src.at<cv::Vec3b>(i,j);
                        std::cout << " " << (int)mask.at<uchar>(i,j);
                    }
                }
            }
            cv::imshow("result",result);
            cv::imshow("mask",mask*20);
        }
        break;
    default:
        break;
    }
}