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()函数中分割模式标志取值范围和含义