• opencvGrabcut图像分割前景与背景


    lm.jpg

    #include<opencv2/opencv.hpp>
    #include<iostream>
    
    
    int main(int argc, char** argv) {
    
        cv::Mat img = cv::imread("D:/bb/tu/lm.jpg");
        imshow("原图像", img);
    
        //绘制矩形
        cv::Mat imgRect;
        img.copyTo(imgRect);  //备份图像
        cv::Rect rect(49, 27, 205, 300);  //前景区域
        rectangle(imgRect, rect, cv::Scalar(255, 255, 255), 1);
        imshow("选择的矩形区域", imgRect);
    
        //进行分割
        cv::Mat bgdmod = cv::Mat::zeros(1, 65, CV_64FC1);
        cv::Mat fgdmod = cv::Mat::zeros(1, 65, CV_64FC1);
        cv::Mat mask = cv::Mat::zeros(img.size(), CV_8UC1);
        grabCut(img, mask, rect, bgdmod, fgdmod, 5, cv::GC_INIT_WITH_RECT);//分割前景和背景
        /*
        参数1:img输入的待分割图像,数据类型为CV_8U的三通道图像
        参数2:mask用于输入、输出的CV_8U单通道掩码图像,图像中像素值的取值范围以及含义在表8-4给出
        参数3:rect包含对象的ROI区域,该参数仅在mode == GC_INIT_WITH_RECT时使用
        参数4:bgdmod背景模型的临时数组
        参数5:fgdmod前景模型的临时数组
        参数6:算法需要进行的迭代次数
        参数7:mode:分割模式标志,该参数值可选择范围以及含义在表8-5给出
        */
    
    
        //将分割出的前景绘制回来
        cv::Mat result;
        for (int row = 0; row < mask.rows; row++) {
            for (int col = 0; col < mask.cols; col++) {
                int n = mask.at<uchar>(row, col);
                if (n == 1 || n == 3) {     //将明显是前景和可能是前景的区域都保留
                    mask.at<uchar>(row, col) = 255;
                }
                else {   //将明显是背景和可能是背景的区域都删除
                    mask.at<uchar>(row, col) = 0;
                }
    
            }
        }
    
        bitwise_and(img, img, result, mask);
        //mask为0的像素变为0,255的像素不变,结果放到result中
        imshow("分割结果", result);
    
        cv::waitKey(0);
        return 0;
    }

    表8-5 grabCut()函数中分割模式标志取值范围和含义

     

  • 相关阅读:
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
  • 原文地址:https://www.cnblogs.com/liming19680104/p/15791211.html
Copyright © 2020-2023  润新知