voidCAssimilation::DeleteObject(float**Data_AssHigh,intheight,intwidth,int*MASK){for(intX_pixel=0;X_pixelheight;X_pixel++){for(intY_pixel=0;Y_pixelwidth;Y_pixel++){if(Data_AssHigh[0][X_pixel*width+Y_pixel]0){MASK[X_pixel*width+Y_pixel]=255;//coutMASK[X_pixel*width+Y_pixel];}}}MatSrcImage1(height,width,CV_8UC1);uchar*ptmp=NULL;for(inti=0;iheight;++i){ptmp=SrcImage1.ptruchar(i);for(intj=0;jwidth;++j){ptmp[j]=MASK[i*width+j];}}//cv::MatSrcImage1=cv::Mat(height,width,CV_8UC1,MASK);容易出问题,导致转换出现问题,采用上面的方式进行转换;MatthresholdImage;cv::threshold(SrcImage1,thresholdImage,0,255,CV_THRESH_OTSU+CV_THRESH_BINARY);vectorvectorPointcontours;//用于保存所有轮廓信息vectorvectorPointcontours2;//用于保存面积不足100的轮廓//vectorPointtempV;//暂存的轮廓cv::findContours(thresholdImage,contours,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);//轮廓按照面积大小进行升序排序sort(contours.begin(),contours.end(),ascendSort);//升序排序vectorvectorPoint::iteratoritc=contours.begin();inti=0;while(itc!=contours.end()){//获得轮廓的矩形边界Rectrect=boundingRect(*itc);intx=rect.x;inty=rect.y;intw=rect.width;inth=rect.height;//绘制轮廓的矩形边界cv::rectangle(SrcImage1,rect,{0,0,255},1);if(itc-size()100){contours2.push_back(*itc);//删除轮廓面积不足100的区域,即用黑色填充轮廓面积不足100的区域:cv::drawContours(SrcImage1,contours2,-1,Scalar(0,0,0),CV_FILLED);}++itc;}for(inti_0=0;i_0height;++i_0){for(intj_0=0;j_0width;++j_0){//if(SrcImage1.atuchar(i_0,j_0)==255)//{MASK[i_0*width+j_0]=SrcImage1.atuchar(i_0,j_0);//inta=MASK[i_0*width+j_0];//}}}//释放内存;vectorvectorPoint().swap(contours);vectorvectorPoint().swap(contours2);}各位,小弟自定义了一个剔除面积小的区域的函数,但是经过多次调用之后会出现处:有未经处理的异常:0xC0000374:堆已损坏。(参数:0x00007FFD3C0C97B0)。经过初步定为是vectorvectorPointcontours;//用于保存所有轮廓信息vectorvectorPointcontours2;//用于保存面积不足100的轮廓的问题,该怎么处理为好?

代码:#include”opencv2/video/tracking.hpp”#include”opencv2/imgproc/imgproc.hpp”#include”opencv2/highgui/highgui.hpp”//#includecv.h#includecxmisc.h#includehighgui.h#includecvaux.h#includeiostream#includectype.h//#includeunistd.h#includestdlib.h#includevector#includestring#includealgorithm#includectype.h#includestdarg.h#includestring.h#includestdio.husingnamespacecv;usingnamespacestd;//vectorPoint2fpoint1,point2;boolleft_mouse=false;Point2fpoint;intpic_info[4];Matgray,prevGray,image,image1;constScalarGREEN=Scalar(0,255,0);intrect_width=0,rect_height=0;PointtmpPoint;intnum=0;intm_frameWidth=640;intm_frameHeight=480;boolm_Calib_Data_Loaded;//是否成功载入定标参数cv::Matm_Calib_Mat_Q;//Q矩阵cv::Matm_Calib_Mat_Remap_X_L;//左视图畸变校正像素坐标映射矩阵Xcv::Matm_Calib_Mat_Remap_Y_L;//左视图畸变校正像素坐标映射矩阵Ycv::Matm_Calib_Mat_Remap_X_R;//右视图畸变校正像素坐标映射矩阵Xcv::Matm_Calib_Mat_Remap_Y_R;//右视图畸变校正像素坐标映射矩阵Ycv::Matm_Calib_Mat_Mask_Roi;//左视图校正后的有效区域cv::Rectm_Calib_Roi_L;//左视图校正后的有效区域矩形cv::Rectm_Calib_Roi_R;//右视图校正后的有效区域矩形doublem_FL;//CvStereoBMState*BMState=cvCreateStereoBMState();intm_numberOfDisparies;//视差变化范围cv::StereoBMm_BM;CvMat*vdisp=cvCreateMat(480,640,CV_8U);cv::Matimg1,img2,img1p,img2p,disp,disp8u,pointClouds,imageLeft,imageRight,disparityImage,imaget1;staticIplImage*framet1=NULL;staticIplImage*framet2=NULL;staticIplImage*framet3=NULL;staticIplImage*framet=NULL;staticvoidonMouse(intevent,intx,inty,int/*flags*/,void*/*param*/){Matmouse_show;image.copyTo(mouse_show);//charbuffer[100];//sprintf(buffer,”D:\l%d.jpg”,num);//stringt1(buffer);//sprintf(buffer,”D:\r%d.jpg”,num);//stringt(buffer);if(event==CV_EVENT_LBUTTONDOWN){pic_info[0]=x;pic_info[1]=y;cout”x:”pic_info[0]”y:”pic_info[1]endl;left_mouse=true;//用于存储打印图片//imwrite(t,image);//imwrite(t1,image1);//num=num++;}elseif(event==CV_EVENT_LBUTTONUP){left_mouse=false;}elseif((event==CV_EVENT_MOUSEMOVE)(left_mouse==true)){}}intloadCalibData(){//读入摄像头定标参数Qroi1roi2mapx1mapy1mapx2mapy2try{cv::FileStoragefs(“calib_paras.xml”,cv::FileStorage::READ);coutfs.isOpened()endl;if(!fs.isOpened()){return(0);}cv::SizeimageSize;cv::FileNodeIteratorit=fs[“imageSize”].begin();itimageSize.widthimageSize.height;//if(imageSize.width!=m_frameWidth||imageSize.height!=m_frameHeight){return(-1);}vectorintroiVal1;vectorintroiVal2;fs[“leftValidArea”]roiVal1;m_Calib_Roi_L.x=roiVal1[0];m_Calib_Roi_L.y=roiVal1[1];m_Calib_Roi_L.width=roiVal1[2];m_Calib_Roi_L.height=roiVal1[3];fs[而不是全体窗口的坐标威尼斯人平台。”rightValidArea”]roiVal2;m_Calib_Roi_R.x=roiVal2[0];m_Calib_Roi_R.y=roiVal2[1];m_Calib_Roi_R.width=roiVal2[2];m_Calib_Roi_R.height=roiVal2[3];fs[“QMatrix”]m_Calib_Mat_Q;fs[“remapX1”]m_Calib_Mat_Remap_X_L;fs[“remapY1”]m_Calib_Mat_Remap_Y_L;fs[“remapX2”]m_Calib_Mat_Remap_X_R;fs[“remapY2”]m_Calib_Mat_Remap_Y_R;cv::MatlfCamMat;fs[“leftCameraMatrix”]lfCamMat;m_FL=lfCamMat.atdouble(0,0);m_Calib_Mat_Q.atdouble(3,2)=-m_Calib_Mat_Q.atdouble(3,2);m_Calib_Mat_Mask_Roi=cv::Mat::zeros(m_frameHeight,m_frameWidth,CV_8UC1);cv::rectangle(m_Calib_Mat_Mask_Roi,m_Calib_Roi_L,cv::Scalar(255),-1);m_BM.state-roi1=m_Calib_Roi_L;m_BM.state-roi2=m_Calib_Roi_R;m_Calib_Data_Loaded=true;stringmethod;fs[“rectifyMethod”]method;if(method!=”BOUGUET”){return(-2);}}catch(std::exceptione){m_Calib_Data_Loaded=false;return(-99);}return1;}voidupdatebm(){m_BM.state-preFilterCap=31;m_BM.state-SADWindowSize=19;m_BM.state-minDisparity=0;m_BM.state-numberOfDisparities=96;m_BM.state-textureThreshold=10;m_BM.state-uniquenessRatio=25;m_BM.state-speckleWindowSize=100;m_BM.state-speckleRange=32;m_BM.state-disp12MaxDiff=-1;}intbmMatch(cv::MatframeLeft,cv::MatframeRight,cv::Matdisparity,cv::MatimageLeft,cv::MatimageRight){//输入检查if(frameLeft.empty()||frameRight.empty()){disparity=cv::Scalar(0);return0;}if(m_frameWidth==0||m_frameHeight==0){//if(init(frameLeft.cols,frameLeft.rows,”calib_paras.xml”/*待改为由本地设置文件确定*/)==0)//执行类初始化//{return0;//}}//转换为灰度图cv::Matimg1proc,img2proc;cvtColor(frameLeft,img1proc,CV_BGR2GRAY);cvtColor(frameRight,img2proc,CV_BGR2GRAY);//校正图像,使左右视图行对齐cv::Matimg1remap,img2remap;//coutm_Calib_Data_Loadedendl;if(m_Calib_Data_Loaded){remap(img1proc,img1remap,m_Calib_Mat_Remap_X_L,m_Calib_Mat_Remap_Y_L,cv::INTER_LINEAR);//对用于视差计算的画面进行校正remap(img2proc,img2remap,m_Calib_Mat_Remap_X_R,m_Calib_Mat_Remap_Y_R,cv::INTER_LINEAR);}else{img1remap=img1proc;img2remap=img2proc;}//对左右视图的左边进行边界延拓,以获取与原始视图相同大小的有效视差区域cv::Matimg1border,img2border;if(m_numberOfDisparies!=m_BM.state-numberOfDisparities)m_numberOfDisparies=m_BM.state-numberOfDisparities;copyMakeBorder(img1remap,img1border,0,0,m_威尼斯人平台,BM.state-numberOfDisparities,0,IPL_BORDER_REPLICATE);copyMakeBorder(img2remap,img2border,0,0,m_BM.state-numberOfDisparities,0,IPL_BORDER_REPLICATE);//计算视差cv::MatdispBorder;m_BM(img1border,img2border,dispBorder);//cvFindStereoCorrespondenceBM(img1border,img2border,dispBorder,BMState);//截取与原始画面对应的视差区域cv::Matdisp;disp=dispBorder.colRange(m_BM.state-numberOfDisparities,img1border.cols);disp.copyTo(disparity,m_Calib_Mat_Mask_Roi);//reprojectImageTo3D(dispBorder,pointClouds,m_Calib_Mat_Q,true);//输出处理后的图像//coutm_Calib_Data_Loadedendl;if(m_Calib_Data_Loaded){remap(frameLeft,imageLeft,m_Calib_Mat_Remap_X_L,m_Calib_Mat_Remap_Y_L,cv::INTER_LINEAR);rectangle(imageLeft,m_Calib_Roi_L,CV_RGB(0,0,255),3);}elseframeLeft.copyTo(imageLeft);if(m_Calib_Data_Loaded)remap(frameRight,imageRight,m_Calib_Mat_Remap_X_R,m_Calib_Mat_Remap_Y_R,cv::INTER_LINEAR);elseframeRight.copyTo(imageRight);rectangle(imageRight,m_Calib_Roi_R,CV_RGB(0,0,255),3);return1;}intgetDisparityImage(cv::Matdisparity,cv::MatdisparityImage,boolisColor){//将原始视差数据的位深转换为8位cv::Matdisp8u;if(disparity.depth()!=CV_8U){if(disparity.depth()==CV_8S){disparity.convertTo(disp8u,CV_8U);}else{disparity.convertTo(disp8u,CV_8U,255/(m_numberOfDisparies*16.));}}else{disp8u=disparity;}//转换为伪彩色图像或灰度图像if(isColor){if(disparityImage.empty()||disparityImage.type()!=CV_8UC3||disparityImage.size()!=disparity.size()){disparityImage=cv::Mat::zeros(disparity.rows,disparity.cols,CV_8UC3);}for(inty=0;ydisparity.rows;y++){for(intx=0;xdisparity.cols;x++){ucharval=disp8u.atuchar(y,x);ucharr,g,b;if(val==0)r=g=b=0;else{r=255-val;g=val128?val*2:(uchar)((255-val)*2);b=val;}disparityImage.atcv::Vec3b(y,x)=cv::Vec3b(r,g,b);}}}else{disp8u.copyTo(disparityImage);}return1;}intgetPointClouds(cv::Matdisparity,cv::MatpointClouds){if(disparity.empty()){return0;}//计算生成三维点云//cv::reprojectImageTo3D(disparity,pointClouds,m_Calib_Mat_Q,true);reprojectImageTo3D(disparity,pointClouds,m_Calib_Mat_Q,true);pointClouds*=1.6;for(inty=0;ypointClouds.rows;++y){for(intx=0;xpointClouds.cols;++x){cv::Point3fpoint=pointClouds.atcv::Point3f(y,x);point.y=-point.y;pointClouds.atcv::Point3f(y,x)=point;}}return1;}voiddetectDistance(cv::MatpointCloud){if(pointCloud.empty()){return;}//提取深度图像vectorcv::MatxyzSet;split(pointCloud,xyzSet);cv::Matdepth;xyzSet[2].copyTo(depth);//根据深度阈值进行二值化处理doublemaxVal=0,minVal=0;cv::MatdepthThresh=cv::Mat::zeros(depth.rows,depth.cols,CV_8UC1);cv::minMaxLoc(depth,minVal,maxVal);doublethrVal=minVal*1.5;threshold(depth,depthThresh,thrVal,255,CV_THRESH_BINARY_INV);depthThresh.convertTo(depthThresh,CV_8UC1);//imageDenoising(depthThresh,3);doubledistance=depth.atfloat(pic_info[0],pic_info[1]);cout”distance:”distanceendl;}

mouseClick (int event, int x, int y, int flags, void* param);

其中event是 CV_EVENT_*变量之一; x和y是鼠标指针在图像坐标系的坐标,并不是整个窗口的坐标;  flags是CV_EVENT_FLAG的组合,  即表示所有的按键,一般情况下是固定的;  param是用户定义的传递到cvSetMouseCallback函数调用的参数,这通常在回调函数中都有类似这种功能的的参数。

Grabcut在opencv中核心算法函数为:

void cv::grabCut( const Mat& img, Mat& mask, Rect rect, Mat& bgdModel,
Mat& fgdModel, int iterCount, int mode )

img——待分割的源图像,必须是8位3通道(CV_8UC3)图像,在处理的过程中不会被修改;

mask——掩码图像,如果使用掩码进行初始化,那么mask保存初始化掩码信息;在执行分割的时候,也可以将用户交互所设定的前景与背景保存到mask中,然后再传入grabCut函数;在处理结束之后,mask中会保存结果。mask只能取以下四种值:

GCD_BGD(=0),背景;

GCD_FGD(=1),前景;

GCD_PR_BGD(=2),可能的背景;

GCD_PR_FGD(=3),可能的前景。

如果没有手工标记GCD_BGD或者GCD_FGD,那么结果只会有GCD_PR_BGD或GCD_PR_FGD;

rect——用于限定需要进行分割的图像范围,只有该矩形窗口内的图像部分才被处理;

bgdModel——背景模型,如果为null,函数内部会自动创建一个bgdModel;bgdModel必须是单通道浮点型(CV_32FC1)图像,且行数只能为1,列数只能为13×5;

fgdModel——前景模型,如果为null,函数内部会自动创建一个fgdModel;fgdModel必须是单通道浮点型(CV_32FC1)图像,且行数只能为1,列数只能为13×5;

iterCount——迭代次数,必须大于0;

mode——用于指示grabCut函数进行什么操作,可选的值有:

GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut;

GC_INIT_WITH_MASK(=1),用掩码图像初始化GrabCut;

GC_EVAL(=2),执行分割。

前景点(Shift+鼠标左键+鼠标移动)和一些背景点(Ctrl+鼠标左键+鼠标移动)

#include”opencv2/imgcodecs.hpp”

#include”opencv2/highgui.hpp”

#include”opencv2/imgproc.hpp”

#include

usingnamespacestd;

usingnamespacecv;

staticvoidhelp()

{

cout<<“nThis program demonstrates GrabCut segmentation — select
an object in a regionn”

“and then grabcut will attempt to segment it out.n”

“Call:n”

“./grabcut n”

“nSelect a rectangular area around the object you want to
segmentn”<<

“nHot keys: n”

“tESC – quit the programn”

“tr – restore the original imagen”

“tn – next iterationn”

“n”

“tleft mouse button – set rectanglen”

“n”

“tCTRL+left mouse button – set GC_BGD pixelsn”

“tSHIFT+left mouse button – set GC_FGD pixelsn”

“n”

“tCTRL+right mouse button – set GC_PR_BGD pixelsn”

“tSHIFT+right mouse button – set GC_PR_FGD pixelsn”<

}

constScalarRED =Scalar(0, 0, 255);

constScalarPINK =Scalar(230, 130, 255);

constScalarBLUE =Scalar(255, 0, 0);

constScalarLIGHTBLUE =Scalar(255, 255, 160);

constScalarGREEN =Scalar(0, 255, 0);

constintBGD_KEY =CV_EVENT_FLAG_CTRLKEY;

constintFGD_KEY =CV_EVENT_FLAG_SHIFTKEY;

staticvoidgetBinMask(constMat&comMask,Mat&binMask)

{

cout<<“getBinMask”<

if(comMask.empty() ||comMask.type() !=CV_8UC1)

CV_Error(CV_StsBadArg,”comMask is empty or has incorrect type (not
CV_8UC1)”);

if(binMask.empty() ||binMask.rows !=comMask.rows ||binMask.cols
!=comMask.cols)

binMask.create(comMask.size(),CV_8UC1);

binMask=comMask&1;

}

classGCApplication

{

public:

enum{NOT_SET= 0,IN_PROCESS= 1,SET= 2 };

staticconstintradius = 2;

staticconstintthickness = -1;

voidreset();

voidsetImageAndWinName(constMat&_image,conststring&_winName);

voidshowImage()const;

voidmouseClick(intevent,intx,inty,intflags,void*param);

intnextIter();

intgetIterCount()const{returniterCount; }

private:

voidsetRectInMask();

voidsetLblsInMask(intflags,Pointp,boolisPr);

conststring* winName;

constMat* image;

Matmask;

MatbgdModel, fgdModel;

ucharrectState, lblsState, prLblsState;

boolisInitialized;

Rectrect;

vector fgdPxls, bgdPxls, prFgdPxls, prBgdPxls;

intiterCount;

};

//清空点集合

voidGCApplication::reset()

{

cout<<“reset”<

if(!mask.empty())

mask.setTo(Scalar::all(GC_BGD));

bgdPxls.clear(); fgdPxls.clear();

prBgdPxls.clear();  prFgdPxls.clear();

isInitialized =false;

rectState =NOT_SET;

lblsState =NOT_SET;

prLblsState =NOT_SET;

iterCount = 0;

}

//初始化,把image赋给全局变量image

voidGCApplication::setImageAndWinName(constMat&_image,conststring&_winName)

{

cout<<“setImageAndWinName”<

if(_image.empty() ||_winName.empty())

return;

image = &_image;

winName = &_winName;

mask.create(image->size(),CV_8UC1);

reset();

}

//负责显示矩形框和画的蓝色区域

voidGCApplication::showImage()const

{

cout<<“showImage”<

if(image->empty() || winName->empty())

return;

Matres;

MatbinMask;

if(!isInitialized) {

cout<<“!isInitialized”<

image->copyTo(res);

}

else

{

cout<<“isInitialized”<

getBinMask(mask, binMask);

image->copyTo(res, binMask);

}

vector::const_iteratorit;

for(it=bgdPxls.begin(); it!=bgdPxls.end();++it) {

//进的这里

//cout << “bgdPxls” << bgdPxls << endl;

//就是为了把以前的点也保存下来,所以不能直接打印

//所以说 bgdPxls

//这里就是为了显示,而真正的mask没在这里

circle(res,*it, radius, BLUE, thickness);

}

for(it=fgdPxls.begin(); it!=fgdPxls.end();++it) {

cout<<“fgdPxls”<

circle(res,*it, radius, RED, thickness);

}

for(it=prBgdPxls.begin(); it!=prBgdPxls.end();++it) {

cout<<“prBgdPxls”<

circle(res,*it, radius, LIGHTBLUE, thickness);

}

for(it=prFgdPxls.begin(); it!=prFgdPxls.end();++it) {

cout<<“prFgdPxls”<

circle(res,*it, radius, PINK, thickness);

}

if(rectState ==IN_PROCESS|| rectState ==SET) {

//意思是无论如何,都要显示出来绿色的矩形框

cout<<“IN_PROCESS || SET”<

rectangle(res,Point(rect.x, rect.y),Point(rect.x + rect.width, rect.y +
rect.height), GREEN, 2);

}

//把res显示出来

imshow(*winName, res);

}

voidGCApplication::setRectInMask()

{

cout<<“setRectInMask”<

assert(!mask.empty());

mask.setTo(GC_BGD);

rect.x = max(0, rect.x);

rect.y = max(0, rect.y);

rect.width = min(rect.width, image->cols – rect.x);

rect.height = min(rect.height, image->rows – rect.y);

(mask(rect)).setTo(Scalar(GC_PR_FGD));

}

voidGCApplication::setLblsInMask(intflags,Pointp,boolisPr)

{

cout<<“setLblsInMask”<

vector *bpxls, *fpxls;

ucharbvalue, fvalue;

if(!isPr)

{

cout<<“这里”;

bpxls = &bgdPxls;

fpxls = &fgdPxls;

bvalue =GC_BGD;

fvalue =GC_FGD;

}

else

{

bpxls = &prBgdPxls;

fpxls = &prFgdPxls;

bvalue =GC_PR_BGD;

fvalue =GC_PR_FGD;

}

if(flags& BGD_KEY)

{

//Add element at the end

//bpxls相当于直接对bgdPxls操作

bpxls->push_back(p);

//cout << “bpxls” << *bpxls;

//cout << “bgdPxls” << bgdPxls;

circle(mask,p, radius, bvalue, thickness);

}

if(flags& FGD_KEY)

{

fpxls->push_back(p);

circle(mask,p, radius, fvalue, thickness);

}

}

//传入x,y的点坐标,然后直接赋值给Point (x,y)——》然后进setLblsInMask

voidGCApplication::mouseClick(intevent,intx,inty,intflags,void*)

{

// TODO add bad args check

switch(event)

{

caseCV_EVENT_LBUTTONDOWN:// set rect or GC_BGD(GC_FGD) labels

{

boolisb = (flags& BGD_KEY) != 0,

isf = (flags& FGD_KEY) != 0;

if(rectState ==NOT_SET&& !isb && !isf)

{

//这里不是按住ctrl的

rectState =IN_PROCESS;

rect=Rect(x,y, 1, 1);

}

if((isb || isf) && rectState ==SET) {

//cout << “这里是按住ctrl之后的CV_EVENT_LBUTTONDOWN” <<
endl;

lblsState =IN_PROCESS;

}

}

break;

/*

case CV_EVENT_RBUTTONDOWN: // set GC_PR_BGD(GC_PR_FGD) labels

{

cout << “CV_EVENT_RBUTTONDOWN”<

bool isb = (flags & BGD_KEY) != 0,

isf = (flags & FGD_KEY) != 0;

if ((isb || isf) && rectState == SET)

prLblsState = IN_PROCESS;

}

break;

*/

caseCV_EVENT_LBUTTONUP:

if(rectState ==IN_PROCESS)

{

//这里不是按住ctrl的

rect=Rect(Point(rect.x, rect.y),Point(x,y));

rectState =SET;

setRectInMask();

assert(bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() &&
prFgdPxls.empty());

showImage();

}

if(lblsState ==IN_PROCESS)

{

//cout << “这里是按住ctrl之后的CV_EVENT_LBUTTONUP” <<
endl;

//把点给mask设置上去

setLblsInMask(flags,Point(x,y),false);

//修改更改状态

lblsState =SET;

//显示image

showImage();

//TODO 这里打印一下mask的值

//cout << ” mask” << mask;

}

break;

/*

case CV_EVENT_RBUTTONUP:

cout << “CV_EVENT_RBUTTONUP” << endl;

if (prLblsState == IN_PROCESS)

{

setLblsInMask(flags, Point(x, y), true);

prLblsState = SET;

showImage();

}

break;

*/

caseCV_EVENT_MOUSEMOVE:

//cout << “CV_EVENT_MOUSEMOVE” << endl;

if(rectState ==IN_PROCESS)

{

//没有按住的

//cout << “画矩形画的点” << endl;

rect=Rect(Point(rect.x, rect.y),Point(x,y));

assert(bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() &&
prFgdPxls.empty());

showImage();

}

elseif(lblsState ==IN_PROCESS)

{

//按住crtl之后移动的点

cout<<“crtl移动”<

setLblsInMask(flags,Point(x,y),false);

showImage();

}

/*

else if (prLblsState == IN_PROCESS)

{

setLblsInMask(flags, Point(x, y), true);

showImage();

}

*/

break;

}

}

intGCApplication::nextIter()

{

if(isInitialized) {

cout<<“init”;

grabCut(*image, mask, rect, bgdModel, fgdModel, 1);

}

else

{

if(rectState !=SET)

returniterCount;

if(lblsState ==SET|| prLblsState ==SET)

{

cout<<“MASK”<<“rect”<

grabCut(*image, mask, rect, bgdModel, fgdModel,
1,GC_INIT_WITH_MASK);

}

else

{

cout<<“RECT”;

grabCut(*image, mask, rect, bgdModel, fgdModel,
1,GC_INIT_WITH_RECT);

}

isInitialized =true;

}

iterCount++;

bgdPxls.clear(); fgdPxls.clear();

prBgdPxls.clear(); prFgdPxls.clear();

returniterCount;

}

GCApplicationgcapp;

staticvoidon_mouse(intevent,intx,inty,intflags,void*param)

{

gcapp.mouseClick(event,x,y,flags,param);

}

intmain(intargc,char**argv)

{

stringfilename =”C:\Users\Mz\Desktop\0327\1.jpg”;

Matimage = imread(filename, 1);

if(image.empty())

{

cout<<“n Durn, couldn’t read image filename “<

return1;

}

help();

conststringwinName =”image”;

namedWindow(winName, 2);

setMouseCallback(winName, on_mouse, 0);

gcapp.setImageAndWinName(image, winName);

gcapp.showImage();

for(;;)

{

intc = waitKey(0);

switch((char)c)

{

case’x1b’:

cout<<“Exiting …”<

gotoexit_main;

case’r’:

cout<

gcapp.reset();

gcapp.showImage();

break;

case’n’:

intiterCount = gcapp.getIterCount();

cout<<“<“<

intnewIterCount = gcapp.nextIter();

if(newIterCount > iterCount)

{

gcapp.showImage();

cout<“<

}

else

cout<<“rect must be determined>”<

break;

}

}

exit_main:

destroyWindow(winName);

return0;

}

相关文章