簡體   English   中英

OpenCV:自定義區域/圖像作為GrabCut的“背景”來源

[英]OpenCV: custom area/image as a source of a “background” for GrabCut

我有要消除某些模式的人像。 請看下面的三個圖像:

GrabCut從第一張圖像中提取了圖形(第二張圖片),沒有任何問題。

現在我有一個與臉部相對應的矩形(第二張圖片上的圓圈),我想將其用作“背景”(而圖像的其余部分將是前景和背景的組合),以消除僅衣服留下的皮膚。

大致所需的結果在第三張圖片上:

GrabCut階段

有什么辦法可以使GrabCut做到這一點? 我無法手動分配區域/遮罩,我所擁有的只是人臉檢測提供的矩形。


UPD:在下面的代碼中,我嘗試使用遮罩進行處理, 但是第2階段似乎不起作用(因為至少應該剪掉面部)。 也許我只是不了解它是如何工作的,因為我剛剛修改了另一個示例代碼正在工作:

static Mat my_segment(Mat _inImage, Rect assumption, Rect face){ 
// human segmentation opencv

        // _inImage - input image
        // assumption - human rectangle on _inImage
        // face - face rectangle on _inImage
        // iterations  - is being set externally


        /* 
        GrabCut segmentation        
        */


        Mat bgModel,fgModel; // the models (internally used)
        Mat result; // segmentation result


        //*********************** step1: GrabCut human figure segmentation
        grabCut(_inImage,    // input image
            result,   // segmentation result
            assumption,// rectangle containing foreground
            bgModel,fgModel, // models
            iterations,        // number of iterations
            cv::GC_INIT_WITH_RECT); // use rectangle

        // Get the pixels marked as likely foreground
        cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);

        // upsample the resulting mask       

        cv::Mat separated(assumption.size(),CV_8UC3,cv::Scalar(255,255,255));
        _inImage(assumption).copyTo(separated,result(assumption));  
         // (bg pixels not copied)

        //return(separated); // return the innerings of assumption rectangle


        //*********************** step2: 
        //cutting the skin with the mask based on the face rectangle
        Rect adjusted_face = face;
        adjusted_face.x = face.x - assumption.x;
        adjusted_face.y = face.y - assumption.y;

        //rectangle(separated,  
        //     adjusted_face.tl(), 
        //     adjusted_face.br(), 
        //     cv::Scalar(166,94,91), 2);  

        //creating mask
        Mat mymask(separated.size(),CV_8UC1);  

        // setting face area as sure background
        mymask.setTo(Scalar::all(GC_PR_FGD));
        mymask(adjusted_face).setTo(Scalar::all(GC_BGD));

        // performing grabcut
        grabCut(separated,
           mymask,
           cv::Rect(0,0,assumption.width,assumption.height),
           bgModel,fgModel,
           1,
           cv::GC_INIT_WITH_MASK);

        // Just repeating everything from before

        // Get the pixels marked as likely foreground
        cv::compare(mymask,cv::GC_PR_FGD,mymask,cv::CMP_EQ);

        //here was the error
        //separated.copyTo(separated,mymask);  // bg pixels not copied

        cv::Mat res(separated.size(),CV_8UC3,cv::Scalar(255,255,255));
        separated.copyTo(res,mymask);  // bg pixels not copied

        //*************************//   

        //return(separated); // return the innerings of assumption rectangle
        return(res);            

} 

好吧,我發現了錯誤,而不是

separated.copyTo(separated,mymask); 

最后幾行應更改為:

cv::Mat res(separated.size(),CV_8UC3,cv::Scalar(255,255,255));
separated.copyTo(res,mymask);  // bg pixels not copied
//*************************//        
return(res); // return the innerings of assumption rectangle

同樣,第二次抓取調用需要更多的迭代次數,例如5-7迭代次數。

結果不是很好,所以我歡迎可以改善它的答案。

結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM