• 大小: 30KB
    文件类型: .zip
    金币: 2
    下载: 1 次
    发布日期: 2021-12-11
  • 语言: 其他
  • 标签: GrabCut  

资源简介

GrabCut源代码实现以及BorderMatting的实现

资源截图

代码片段和文件信息

#include “BorderMatting.h“
BorderMatting::BorderMatting(){}
BorderMatting::~BorderMatting(){}
//判断x是否在l和r直接。
inline bool outrange(int _x int _l int _r){
if (_x<_l || _x>_r) return true;
else return false;
}
//变量初始化。
void BorderMatting::init(const Mat& _img){
rows = _img.rows;
cols = _img.cols;
sections = 0;
areaCount = 0;
contour.clear();
strip.clear();
vecds.clear();
}
//利用 Canny 算法进行边缘检测,结果存放在 _rs 中。
void BorderDetection(const Mat& _img Mat& _rs){
Mat edges;
Canny(_img edges 3 9);
edges.convertTo(_rs CV_8UC1);
}
//深度优先搜索遍历整个轮廓,并对 contour 进行构造。
void BorderMatting::dfs(int _x int _y const Mat& _edge Mat& _color){
//标记遍历到的点
_color.at(_x _y) = 255;
para_point pt;
pt.p.x = _x; pt.p.y = _y; //坐标
pt.index = areaCount++;//给轮廓上每一个点分配独立index
pt.section = sections;//所属轮廓
contour.push_back(pt); //放入轮廓vector
//枚举(xy)相邻点
for (int i = 0; i < nstep; i++) {
int zx = nx[i] zy = ny[i];
int newx = _x + zx newy = _y + zy;
//超出图像范围
if (outrange(newx 0 rows - 1) || outrange(newy 0 cols - 1)) continue;
//不是轮廓上的点
if (_edge.at(newx newy) == 0)continue;
//已经被遍历过
if (_color.at(newx newy) != 0)continue;
//从(newxnewy)出发,继续深搜遍历轮廓
dfs(newx newy _edge _color);
}
}
//利用深度优先搜索对轮廓进行参数计算。
void BorderMatting::ParameterizationContour(const Mat& _edge)
{
int rows = _edge.rows cols = _edge.cols;
sections = 0; 
areaCount = 0; 
//遍历标记
Mat color(_edge.size() CV_8UC1 Scalar(0));
bool flag = false;
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
//(ij)是轮廓上的点且未被遍历过
if (_edge.at(i j) != 0 && color.at(i j) == 0){
//对其进行遍历并使轮廓数加一
dfs(i j _edge color);
sections++;
}
}
//初始化TU,用无序图来存储,hash 值就是其坐标值。
void BorderMatting::StripInit(const Mat& _mask){
Mat color(_mask.size() CV_32SC1 Scalar(0));//遍历标记
//从轮廓出发,宽搜标记TU,标记TU所属区域————对应的中心轮廓点
//初始化队列:加入轮廓上所有点
vector queue;
for (int i = 0; i < contour.size(); i++){
inf_point ip;
ip.p = contour[i].p; //坐标
ip.dis = 0; //距离中心点的欧氏距离
ip.area = contour[i].index; //所属区域
strip[ip.p.x*COE + ip.p.y] = ip; //将点加入条带,key(hash)值为其坐标
queue.push_back(ip.p); //将点加入队列
color.at(ip.p.x ip.p.y) = ip.area + 1; //遍历标记:区域号+1
}
//宽搜遍历TU,将
int l = 0;
while (l < queue.size()){
point p = queue[l++]; //取出点
inf_point ip = strip[p.x*COE + p.y]; //从strip中得到相关信息
//只遍历TU内的点
if (abs(ip.dis) >= stripwidth) break;
int x = ip.p.x y = ip.p.y;
//枚举相邻点
for (int i = 0; i < rstep; i++) {
int newx = x + rx[i] newy = y + ry[i];
//超出图像范围
if (outrange(newx 0 rows - 1) || outrange(newy 0 cols - 1)) continue;
inf_point nip;
//如果已经被遍历过
if (color.at(newx newy) != 0) continue;
else nip.p.x = newx; nip.p.y = newy;
nip.dis = abs(ip.dis) + 1;//欧式距离+1
//如果该点属于背景,欧氏距离取负
if ((_mask.at(newx newy) & 1) != 1) nip.dis = -nip.dis;
nip.area = ip.area;
//加入TU中。

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     文件        7220  2010-01-25 12:00  block.h
     文件       12564  2017-06-10 22:09  BorderMatting.cpp
     文件        2665  2017-06-08 07:51  BorderMatting.h
     文件         708  2017-06-06 18:58  CutGraph.cpp
     文件         337  2017-06-06 18:57  CutGraph.h
     文件        5598  2017-06-08 07:52  GCApplication.cpp
     文件        1943  2017-06-08 07:53  GCApplication.h
     文件        5991  2017-06-07 23:28  GMM.cpp
     文件        1948  2017-06-07 23:00  GMM.h
     文件        9815  2017-06-10 21:38  GrabCut.cpp
     文件         451  2017-06-07 13:19  GrabCut.h
     文件        2916  2010-01-25 12:00  graph.cpp
     文件       17233  2010-01-25 12:00  graph.h
     文件         394  2010-01-25 12:00  instances.inc
     文件        2207  2017-06-08 07:52  main.cpp
     文件       14887  2010-01-25 12:00  maxflow.cpp
     文件         363  2017-06-11 09:07  README.md

评论

共有 条评论