暑假时候复现的一篇计算机视觉经典抠图算法grabcut的论文,“GrabCut” — Interactive Foreground Extraction using Iterated Graph Cuts
代码存一下,虽然我转行了不搞cv了hhh
myGrabCut.h
#pragma once
#include<graph.cpp>
#include<opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/types.hpp>
#include<string>
typedef Graph<double, double, double> GraphType;
using namespace cv;
class GMM {
public:
Mat model;
static const int compo_k = 5;
double coefs[compo_k];
double mean[compo_k][3];
double covs[compo_k][3][3];
double inv_covs[compo_k][3][3];
double det_covs[compo_k];
double sums[compo_k][3];
double prods[compo_k][3][3];
int sample_num[compo_k];
int tot_sample_num;
GMM();
void calc_inv_det(int ci);
double prob_GMM(const Vec3d color) const;
double prob_Gi(int ci, const Vec3d color) const;
int sle_compo(const Vec3d color) const;
void init_param();
void add_pixel(int ci, const Vec3d color);
void esti_param();
};
static double calcBeta(const Mat& img);
/*
Calculate weights of noterminal vertices of graph.
beta and gamma - parameters of GrabCut algorithm.
*/
static void calcNWeights(const Mat& img, Mat& leftW, Mat& upleftW, Mat& upW,
Mat& uprightW, double beta, double gamma);
/*
Check size, type and element values of mask matrix.
*/
static void checkMask(const Mat& img, const Mat& mask);
/*
Initialize mask using rectangular.
*/
static void initMaskWithRect(Mat& mask, Size imgSize, Rect rect);
/*
Initialize GMM background and foreground models using kmeans algorithm.
*/
static void initGMMs(const Mat& img, const Mat& mask, GMM& bgdGMM, GMM& fgdGMM);
/*
Assign GMMs components for each pixel.
*/
static void assignGMMsComponents(const Mat& img, const Mat& mask, const GMM& bgdGMM,
const GMM& fgdGMM, Mat& compIdxs);
//论文中:迭代最小化算法step 2:从每个高斯模型的像素样本集中学习每个高斯模型的参数
/*
Learn GMMs parameters.
*/
static void learnGMMs(const Mat& img, const Mat& mask, const Mat& compIdxs, GMM& bgdGMM, GMM& fgdGMM);
/*
Construct GCGraph
*/
static void constructGCGraph(const Mat& img, const Mat& mask, const GMM& bgdGMM, const GMM& fgdGMM, double lambda,
const Mat& leftW, const Mat& upleftW, const Mat& upW, const Mat& uprightW,
GraphType*& graph);
/*
Estimate segmentation using MaxFlow algorithm
*/
static void estimateSegmentation(GraphType* graph, Mat& mask, std::vector<double>& result);
void mygrabCut(InputArray _img, InputOutputArray _mask, Rect rect,
InputOutputArray _bgdModel, InputOutputArray _fgdModel,
int iterCount, int mode);//,std::vector<double>& result);
主程序代码,其中最大流最小割直接用了maxflow-v3.01的库,其他调用了一些OpenCv的基本接口我不会说我就是照着OpenCv的库函数写的
继续阅读“[CV][经典算法] Grab Cut C++实现”