欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenCV使用GrabCut實(shí)現(xiàn)摳圖功能

 更新時(shí)間:2023年02月19日 11:08:42   作者:音視頻開發(fā)老舅  
Grabcut是基于圖割(graph cut)實(shí)現(xiàn)的圖像分割算法,它需要用戶輸入一個(gè)bounding box作為分割目標(biāo)位置,實(shí)現(xiàn)對(duì)目標(biāo)與背景的分離/分割。本文將使用GrabCut實(shí)現(xiàn)摳圖功能,需要的可以參考一下

1、概述

案例:使用OpenCV的GrapCut實(shí)現(xiàn)有用戶交互的摳圖

grabCut( InputArray img, InputOutputArray mask, Rect rect,
                           InputOutputArray bgdModel, InputOutputArray fgdModel,
                           int iterCount, int mode = GC_EVAL );
  • img --> 輸入的三通道圖像;
  • mask --> 輸入的單通道圖像,初始化方式為GC_INIT_WITH_RECT表示ROI區(qū)域可以被初始化為:
  • GC_BGD --> 定義為明顯的背景像素 0
  • GC_FGD --> 定義為明顯的前景像素 1
  • GC_PR_BGD --> 定義為可能的背景像素 2
  • GC_PR_FGD --> 定義為可能的前景像素 3
  • rect --> 表示roi區(qū)域;
  • bgdModel --> 表示臨時(shí)背景模型數(shù)組;
  • fgdModel --> 表示臨時(shí)前景模型數(shù)組;
  • iterCount --> 表示圖割算法迭代次數(shù), 次數(shù)越多,效果越好;
  • mode --> 當(dāng)使用用戶提供的roi時(shí)候使用GC_INIT_WITH_RECT

實(shí)現(xiàn)算法的步驟:

1.創(chuàng)建一個(gè)遮罩,并初始化為背景GC_BGD

2.用戶選定一個(gè)ROI區(qū)域初始化為前景GC_FGD

3.調(diào)用grabCut函數(shù)實(shí)現(xiàn)算法

4.輸入mask即為目標(biāo)摳圖

2、代碼示例

(這個(gè)例子不完善,圖像的顏色輸出有問題,先記錄一下,后面改正。但是不影響整個(gè)算法的流程及效果,僅僅是RGB和BGR像素通道的問題)

CrabCut_Matting::CrabCut_Matting(QWidget *parent)
    : MyGraphicsView{parent}
{
    this->setWindowTitle("crabCut摳圖");
    this->setMouseTracking(true);//設(shè)置鼠標(biāo)事件可用
    init = false;
    numRun = false;
}
 
 
void CrabCut_Matting::dropEvent(QDropEvent*event){
    QString filePath = event->mimeData()->urls().at(0).toLocalFile();
    showCrabCutMatting(filePath.toStdString().c_str());
}
 
void CrabCut_Matting::showCrabCutMatting(const char* filePath){
    src = imread(filePath);
    if(src.empty()){
        qDebug()<<"輸入圖像為空";
        return;
    }
 
    //創(chuàng)建一個(gè)背景遮罩
    mMask = Mat::zeros(src.size(),CV_8UC1);
    mMask.setTo(Scalar::all(GC_BGD));
 
 
    convert2Sence(src);
}
void CrabCut_Matting::mouseMoveEvent(QMouseEvent *event){
    //    if(event->button()==Qt::LeftButton){//鼠標(biāo)左鍵
    rect = Rect(Point(rect.x, rect.y), Point(event->pos().x(), event->pos().y()));
    qDebug()<<"mouseMoveEvent:"<<rect.width<<"|"<<rect.height;
    showImage();
    //    }
}
 
void CrabCut_Matting::mousePressEvent(QMouseEvent *event){
    grabMouse();
    if(event->button()==Qt::LeftButton){//鼠標(biāo)左鍵
        rect.x = event->pos().x();
        rect.y = event->pos().y();
        rect.width = 1;
        rect.height = 1;
        init = false;
        numRun = 0;
        qDebug()<<"mousePressEvent:"<<event->pos().x()<<"|"<<event->pos().y();
    }
 
}
 
void CrabCut_Matting::mouseReleaseEvent(QMouseEvent *event){
    releaseMouse();
    if(event->button()==Qt::LeftButton){//鼠標(biāo)左鍵
        if (rect.width > 1 && rect.height > 1) {
            setROIMask();
            qDebug()<<"mouseReleaseEvent:"<<rect.width<<"|"<<rect.height;
            //執(zhí)行g(shù)rabcut的代碼
            runGrabCut();
            numRun++;
            showImage();
        }
 
    }
}
/**
 * 將選中的區(qū)域設(shè)置為前景
 * @brief CrabCut_Matting::setROIMask
 */
void CrabCut_Matting::setROIMask(){
    // GC_FGD = 1
    // GC_BGD =0;
    // GC_PR_FGD = 3
    // GC_PR_BGD = 2
    mMask.setTo(GC_BGD);
    rect.x = max(0, rect.x);
    rect.y = max(0, rect.y);
    rect.width = min(rect.width, src.cols - rect.x);
    rect.height = min(rect.height, src.rows - rect.y);
    mMask(rect).setTo(Scalar(GC_PR_FGD));//將選中的區(qū)域設(shè)置為
}
 
void CrabCut_Matting::showImage(){
    Mat result, binMask;
    binMask.create(mMask.size(), CV_8UC1);
    binMask = mMask & 1;
    if (init) {
        src.copyTo(result, binMask);
    } else {
        src.copyTo(result);
    }
    rectangle(result, rect, Scalar(0, 0, 255), 2, 8);
    convert2Sence(result);
 
}
 
 
void CrabCut_Matting::runGrabCut(){
    if (rect.width < 2 || rect.height < 2) {
        return;
    }
 
    if (init) {
        grabCut(src, mMask, rect, bgModel, fgModel, 1);
    } {
        grabCut(src, mMask, rect, bgModel, fgModel, 1, GC_INIT_WITH_RECT);
        init = true;
    }
}
 
 
void CrabCut_Matting::convert2Sence(Mat target){
    scene.clear();
    QImage image = ImageUtils::matToQImage(target);
    QPixmap pixmap = QPixmap::fromImage(image);
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap.scaled(this->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
    scene.addItem(item);
}

3、示例圖片

以上就是OpenCV使用GrabCut實(shí)現(xiàn)摳圖功能的詳細(xì)內(nèi)容,更多關(guān)于OpenCV GrabCut摳圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++中的數(shù)據(jù)對(duì)齊示例詳解

    C++中的數(shù)據(jù)對(duì)齊示例詳解

    這篇文章主要介紹了C++中數(shù)據(jù)對(duì)齊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C++實(shí)現(xiàn)四則運(yùn)算器(帶括號(hào))

    C++實(shí)現(xiàn)四則運(yùn)算器(帶括號(hào))

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)四則運(yùn)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Qt出現(xiàn)假死凍結(jié)現(xiàn)象的原因及解決方法

    Qt出現(xiàn)假死凍結(jié)現(xiàn)象的原因及解決方法

    應(yīng)用程序出現(xiàn)假死或凍結(jié)現(xiàn)象通常是由于一些常見問題所導(dǎo)致的,本文主要介紹了Qt出現(xiàn)假死凍結(jié)現(xiàn)象的原因及解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 淺談C#互操作的內(nèi)存溢出問題

    淺談C#互操作的內(nèi)存溢出問題

    以前了解過c++的棧內(nèi)存溢出,沒想到在c#里被我遇到了,問題看似不大,如何被恰好相鄰的四個(gè)字節(jié)是返回地址,說不定危害不小啊!看來c#的互操作還是得小心為好
    2013-10-10
  • C語言實(shí)現(xiàn)enum枚舉

    C語言實(shí)現(xiàn)enum枚舉

    在實(shí)際編程中,有些數(shù)據(jù)的取值往往是有限的,只能是非常少量的整數(shù),并且最好為每個(gè)值都取一個(gè)名字,以方便在后續(xù)代碼中使用,比如一個(gè)星期只有七天,一年只有十二個(gè)月,一個(gè)班每周有六門課程等。 以每周七天為例,我們可以使用#define命令來給每天指定一個(gè)名字
    2021-06-06
  • C++的對(duì)象特性和友元你真的了解嗎

    C++的對(duì)象特性和友元你真的了解嗎

    這篇文章主要為大家詳細(xì)介紹了C++的對(duì)象特性和友元,使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 你真的知道C++對(duì)象大小嗎?

    你真的知道C++對(duì)象大小嗎?

    這篇文章主要給大家介紹了關(guān)于C++對(duì)象大小的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C語言?如何用堆解決Topk問題

    C語言?如何用堆解決Topk問題

    TopK問題即在N個(gè)數(shù)中找出最大的前K個(gè),這篇文章將詳細(xì)講解如何利用小根堆的方法解決TopK問題,文中代碼具有一定參考價(jià)值,快跟隨小編一起學(xué)習(xí)一下吧
    2021-12-12
  • c++ 寫注冊(cè)表方式讓程序開機(jī)自啟動(dòng)

    c++ 寫注冊(cè)表方式讓程序開機(jī)自啟動(dòng)

    這篇文章主要介紹了c++ 寫注冊(cè)表方式讓程序開機(jī)自啟動(dòng),需要的朋友可以參考下
    2017-09-09
  • opencv實(shí)現(xiàn)機(jī)器視覺檢測和計(jì)數(shù)的方法

    opencv實(shí)現(xiàn)機(jī)器視覺檢測和計(jì)數(shù)的方法

    在機(jī)器視覺中,有時(shí)需要對(duì)產(chǎn)品進(jìn)行檢測和計(jì)數(shù)。其難點(diǎn)無非是對(duì)于產(chǎn)品的圖像分割。本文就來介紹一下機(jī)器視覺檢測和計(jì)數(shù)的實(shí)現(xiàn),感興趣的可以參考一下
    2021-05-05

最新評(píng)論