c++ - 从背景中分割前景

标签 c++ opencv image-segmentation

我目前正在做一个使用Lacatan Banana 的项目,我想知道如何进一步将前景与背景分开:

我已经使用腐 eclipse 、膨胀和阈值处理得到了它的分割图像。问题是它仍然没有正确分割。

这是我的代码:

    cv::Mat imggray, imgthresh, fg, bgt, bg;
    cv::cvtColor(src, imggray, CV_BGR2GRAY); //Grayscaling the image from RGB color space
    cv::threshold(imggray, imgthresh, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU); //Create an inverted binary image from the grayscaled image
    cv::erode(imgthresh, fg, cv::Mat(), cv::Point(-1, -1), 1); //erosion of the binary image and setting it as the foreground
    cv::dilate(imgthresh, bgt, cv::Mat(), cv::Point(-1, -1), 4); //dilation of the binary image to reduce the background region
    cv::threshold(bgt, bg, 1, 128, CV_THRESH_BINARY); //we get the background by setting the threshold to 1
    cv::Mat markers = cv::Mat::zeros(src.size(), CV_32SC1); //initializing the markers with a size same as the source image and setting its data type as 32-bit Single channel
    cv::add(fg, bg, markers); //setting the foreground and background as markers                                                                
    cv::Mat mask = cv::Mat::zeros(markers.size(), CV_8UC1);
    markers.convertTo(mask, CV_8UC1);    //converting the 32-bit single channel marker to a 8-bit single channel
    cv::Mat mthresh;
    cv::threshold(mask, mthresh, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); //threshold further the mask to reduce the noise
    // cv::erode(mthresh,mthresh,cv::Mat(), cv::Point(-1,-1),2);
    cv::Mat result;
    cv::bitwise_and(src, src, result, mthresh);  //use the mask to subtrack the banana from the background
    for (int x = 0; x < result.rows; x++) { //changing the black background to white
        for (int y = 0; y < result.cols; y++) {
            if (result.at<Vec3b>(x, y) == Vec3b(0, 0, 0)){
                result.at<Vec3b>(x, y)[0] = 255;
                result.at<Vec3b>(x, y)[1] = 255;
                result.at<Vec3b>(x, y)[2] = 255;
            }
        }
    }

这是我的结果:

最佳答案

由于背景接近灰色,请尝试使用色调 channel 和饱和度 channel 而不是灰度图像。
您可以轻松获得它们。

cv::Mat hsv;
cv::cvtColor(src, hsv, CV_BGR2HSV);
std::vector<cv::Mat> channels;
cv::split(src, channels);

cv::Mat hue = channels[0];
cv::Mat saturation = channels[1];

// If you want to combine those channels, use this code.
cv::Mat hs = cv::Mat::zeros(src.size(), CV_8U);
for(int r=0; r<src.rows; r++) {
    for(int c=0; c<src.cols; c++) {
        int hp = h.at<uchar>(r,c);
        int sp = s.at<uchar>(r,c);
        hs.at<uchar>(r, c) = static_cast<uchar>((h+s)>>1);
    }
}

关于c++ - 从背景中分割前景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36004948/

相关文章:

c++ - 将 boost::fusion::for_each 应用于具有可变函数对象的 boost::fusion::vector

c++ - 如何强制 ld 使用静态库而不是共享库?

python - 模板使用opencv匹配屏幕截图

python - Numpy where() 创建与定义颜色不同的点

tensorflow - 如何在语义分割中删除特定标记的像素

c++ - 处理 bad_alloc 时使用 cerr 是否安全?

c++ - g++ : expected primary-expression before ‘[’ token

opencv - 为什么 cv_bridge 在 ROS Melodic 中使用 OpenCV 3.2?

c++ - openCV 2.4.9 与 CUDA 6.5 的编译错误

image - GrabCut 分割是否取决于图像的大小?