首页 > 代码库 > 非零点之间聚类
非零点之间聚类
在二值图像中,非零点之间的进行聚类,使用矩形框进行标记其区域过程中,主要解决相邻的两个矩形框之间重叠区域和嵌套现象。仅作參考.(注:因开发周期仅仅有几个小时的时间.代码有不规范地方,请各位见谅).
cvRectOject头文件
/** * * File : cvRectObject.h. * Author : Gavin Liu * Date : 2014-03-20 * Version : V1.0.0.0 */ #ifndef _CVRECTOBJECT_H_ #define _CVRECTOBJECT_H_ #define CONTOUR_MAX_AREA 200 #define _NV_INFO_OBJRECT_ #define CV_ALGRITHM_MORPHOLOGY 0 #define CV_ALGRITHM_FOOLFILL 1 struct RectObject{ //矩形框结构 int nx; //左上角坐标点的X轴 int ny; //左上角坐标点的Y轴 int nWidth; //矩形框的宽度 int nHeight; //矩形框的高度 int nReserved[8]; //保留 }; typedef std::vector<RectObject> VRectObj; typedef std::vector<Point> VPointObj; void cvObjectRectMorphology(const IplImage *pImg, VRectObj &vecRectRoi, VRectObj &vecRectResult, int flags); void cvObjectRectCluster(VRectObj &vecRect, VRectObj &vecRectResult); #endif //_CVRECTOBJECT_H_
cvRectOject.cpp文件
#include "cvRectObject.h" inline int cvDataMax (int V1,int V2,int V3, int V4){ int temp1 = V1>V2?V1:V2; int temp2 = V3>V4?V3:V4; return(temp1>temp2?temp1:temp2); } inline int cvDataMin (int V1,int V2,int V3, int V4){ int temp1 = V1< V2 ? V1:V2; int temp2 = V3< V4 ? V3:V4; return(temp1< temp2 ? temp1 : temp2); } void cvMergeRect(VRectObj &srcVRectObj,bool flags){ VRectObj::size_type ix,iy; CvPoint pt1,pt2,pt3,pt4; CvPoint Tpt1,Tpt2,CTpt1,CTpt2; for( ix =0; ix < srcVRectObj.size();ix++){ if((srcVRectObj[ix].nx !=0)&&(srcVRectObj[ix].ny !=0)&&(srcVRectObj[ix].nHeight !=0)&&(srcVRectObj[ix].nWidth !=0)){ pt1.x = srcVRectObj[ix].nx; pt1.y = srcVRectObj[ix].ny; pt2.x = srcVRectObj[ix].nx +srcVRectObj[ix].nWidth; pt2.y = srcVRectObj[ix].ny +srcVRectObj[ix].nHeight; for(iy =0; iy <srcVRectObj.size()&&(iy !=ix); iy++){ if((srcVRectObj[iy].nx !=0)&&(srcVRectObj[iy].ny !=0)&&(srcVRectObj[iy].nWidth !=0)&&(srcVRectObj[iy].nHeight !=0)){ pt3.x = srcVRectObj[iy].nx; pt3.y = srcVRectObj[iy].ny; pt4.x = srcVRectObj[iy].nx +srcVRectObj[iy].nWidth; pt4.y = srcVRectObj[iy].ny +srcVRectObj[iy].nHeight; if(((pt1.x<=pt3.x)&&(pt4.x<=pt2.x)&&(pt1.y<=pt3.y)&&(pt4.y<=pt2.y))|| ((pt1.x>=pt3.x)&&(pt4.x>=pt2.x)&&(pt1.y>=pt3.y)&&(pt4.y>=pt2.y))){ if((srcVRectObj[ix].nWidth >srcVRectObj[iy].nWidth)&&(srcVRectObj[ix].nHeight >srcVRectObj[iy].nHeight)){ srcVRectObj[iy].nx =0; srcVRectObj[iy].ny =0; srcVRectObj[iy].nWidth =0; srcVRectObj[iy].nHeight =0; } else{ srcVRectObj[ix].nx =0; srcVRectObj[ix].ny =0; srcVRectObj[ix].nWidth =0; srcVRectObj[ix].nHeight =0; } } if(((pt4.x>=pt1.x)&&(pt4.x <=pt2.x))&&(((pt1.y<=pt4.y)&&(pt2.y >= pt4.y))||((pt1.y<=pt3.y)&&(pt2.y>=pt3.y)))|| (((pt3.x>=pt1.x)&&(pt3.x <=pt2.x))&&(((pt1.y<=pt3.y)&&(pt2.y>=pt3.y))||((pt1.y <=pt4.y)&&(pt2.y>=pt4.y))))){ Tpt1.x = cvDataMin(pt1.x,pt2.x,pt3.x,pt4.x); Tpt1.y = cvDataMin(pt1.y,pt2.y,pt3.y,pt4.y); Tpt2.x = cvDataMax(pt1.x,pt2.x,pt3.x,pt4.x); Tpt2.y = cvDataMax(pt1.y,pt2.y,pt3.y,pt4.y); if(ix < iy){ srcVRectObj[ix].nx =Tpt1.x; srcVRectObj[ix].ny =Tpt1.y; srcVRectObj[ix].nWidth = abs(Tpt2.x - Tpt1.x); srcVRectObj[ix].nHeight = abs(Tpt2.y -Tpt1.y); srcVRectObj[iy].nx =0; srcVRectObj[iy].ny =0; srcVRectObj[iy].nWidth =0; srcVRectObj[iy].nHeight =0; } else if(ix> iy){ srcVRectObj[iy].nx =Tpt1.x; srcVRectObj[iy].ny =Tpt1.y; srcVRectObj[iy].nWidth = abs(Tpt2.x - Tpt1.x); srcVRectObj[iy].nHeight = abs(Tpt2.y -Tpt1.y); srcVRectObj[ix].nx =0; srcVRectObj[ix].ny =0; srcVRectObj[ix].nWidth =0; srcVRectObj[ix].nHeight =0; } } CTpt1.x = srcVRectObj[ix].nx +int(0.5*(srcVRectObj[ix].nWidth)); CTpt1.y = srcVRectObj[ix].ny +int(0.5*(srcVRectObj[ix].nHeight)); CTpt2.x = srcVRectObj[iy].nx +int(0.5*(srcVRectObj[iy].nWidth)); CTpt2.y = srcVRectObj[iy].ny +int(0.5*(srcVRectObj[iy].nHeight)); double Xdist = abs(CTpt1.x -CTpt2.x); double Ydist = abs(CTpt1.y -CTpt2.y); double Dist = sqrt(Xdist*Xdist +Ydist*Ydist); double ThrVal= cvDataMax(srcVRectObj[ix].nHeight,srcVRectObj[ix].nWidth,srcVRectObj[iy].nHeight,srcVRectObj[iy].nWidth); if(Dist <= ThrVal){ Tpt1.x = cvDataMin(pt1.x,pt2.x,pt3.x,pt4.x); Tpt1.y = cvDataMin(pt1.y,pt2.y,pt3.y,pt4.y); Tpt2.x = cvDataMax(pt1.x,pt2.x,pt3.x,pt4.x); Tpt2.y = cvDataMax(pt1.y,pt2.y,pt3.y,pt4.y); if(ix<iy){ srcVRectObj[ix].nx =Tpt1.x; srcVRectObj[ix].ny =Tpt1.y; srcVRectObj[ix].nWidth = abs(Tpt2.x - Tpt1.x); srcVRectObj[ix].nHeight = abs(Tpt2.y -Tpt1.y); srcVRectObj[iy].nx =0; srcVRectObj[iy].ny =0; srcVRectObj[iy].nWidth =0; srcVRectObj[iy].nHeight =0; } if(ix>iy){ srcVRectObj[iy].nx =Tpt1.x; srcVRectObj[iy].ny =Tpt1.y; srcVRectObj[iy].nWidth = abs(Tpt2.x - Tpt1.x); srcVRectObj[iy].nHeight = abs(Tpt2.y -Tpt1.y); srcVRectObj[ix].nx =0; srcVRectObj[ix].ny =0; srcVRectObj[ix].nWidth =0; srcVRectObj[ix].nHeight =0; } } } //end of iy_if }// end of iy_for } // end of ix_if } //end of ix_for } void cvObjectRectMorphology( const IplImage *pImg,VRectObj &vecRectRoi, VRectObj &vecRectResult,int flags){ IplImage * pImgtemp = NULL; IplImage * pBinaryImg = NULL; if(!pImg){ printf("Could not load File in the cvLoadImage(...).\n"); exit(EXIT_FAILURE); } pImgtemp = cvCreateImage(cvGetSize(pImg),IPL_DEPTH_8U,1); if(pImg->nChannels ==1){ pImgtemp = cvCloneImage(pImg); } if(pImg->nChannels ==3){ cvCvtColor(pImg,pImgtemp,CV_RGB2GRAY); } pBinaryImg = cvCloneImage(pImgtemp); if( flags == CV_ALGRITHM_FOOLFILL){ CvPoint beginPoint; for(int i =0; i<pImgtemp->height; i++){ for(int j =0; j<pImgtemp->width; j++){ CvScalar cs = cvGet2D(pImgtemp,i,j); if(cs.val[0] !=0){ beginPoint.x = j; beginPoint.y = i; } } } IplImage *pMask = cvCreateImage(cvSize(pImgtemp->width +2 ,pImgtemp->height +2),8,1); cvSetZero(pMask); cvSmooth(pImgtemp,pImgtemp,CV_GAUSSIAN,3,0,0,0); cvFloodFill(pImgtemp,beginPoint,CV_RGB(255,0,0),CV_RGB(0,255,0),cvScalarAll(10),NULL,CV_FLOODFILL_FIXED_RANGE,pMask); } if(flags == CV_ALGRITHM_MORPHOLOGY){ cvSmooth(pImgtemp,pImgtemp,CV_GAUSSIAN,3,0,0,0); cvMorphologyEx(pImgtemp,pImgtemp,NULL,0,CV_MOP_GRADIENT,1); } CvMemStorage *stor = cvCreateMemStorage(0); CvSeq* cont =cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor); cvFindContours(pImgtemp,stor,&cont,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0)); CvPoint pt1,pt2; std::vector<CvRect> vecRect; for(;cont!=0;cont=cont->h_next){ //cvDrawContours(pImgtemp,cont,CV_RGB(255,0,0),CV_RGB(0,255,0),0,2,0); CvRect r =((CvContour*)cont)->rect; if((r.height*r.width <CONTOUR_MAX_AREA)){ cvSeqRemove(cont,0); continue; } else{ pt1 = cvPoint(r.x,r.y); pt2 = cvPoint(r.x+r.width,r.y+r.height); //cvRectangle(pBinaryImg,pt1,pt2,CV_RGB(0,255,0),2,CV_AA,0); vecRect.push_back(r); continue; } } cvReleaseMemStorage(&stor); RectObject Objrect; VRectObj vecObjtemp; for(vector<CvRect>::size_type ix =0; ix < vecRect.size(); ix++){ Objrect.nx = vecRect[ix].x; Objrect.ny = vecRect[ix].y; Objrect.nHeight = vecRect[ix].height; Objrect.nWidth = vecRect[ix].width; vecObjtemp.push_back(Objrect); } cvObjectRectCluster(vecObjtemp,vecRectResult); cvReleaseImage(&pImgtemp); cvReleaseImage(&pBinaryImg); } void cvObjectRectCluster(VRectObj& vecRect,VRectObj &vecRectResult){ if(vecRect.empty()){ std::cerr <<"The Vector of vecRect is empty!"<<std::endl; exit(EXIT_FAILURE); } Point CenPoint; VPointObj vecPoint; VRectObj::size_type Ci,Cii; RectObject rObj; for( Ci = 0; Ci<vecRect.size(); Ci++){ for(Cii = Ci+1; Cii<vecRect.size(); Cii++){ if((vecRect[Ci].nx > vecRect[Cii].nx)||(vecRect[Ci].nx ==vecRect[Ci].nx)&&(vecRect[Ci].ny > vecRect[Cii].ny)){ rObj.nx = vecRect[Ci].nx; rObj.ny = vecRect[Ci].ny; rObj.nWidth = vecRect[Ci].nWidth; rObj.nHeight = vecRect[Ci].nHeight; vecRect[Ci].nx = vecRect[Cii].nx; vecRect[Ci].ny = vecRect[Cii].ny; vecRect[Ci].nWidth = vecRect[Cii].nWidth; vecRect[Ci].nHeight = vecRect[Cii].nHeight; vecRect[Cii].nx = rObj.nx; vecRect[Cii].ny = rObj.ny; vecRect[Cii].nWidth = rObj.nWidth; vecRect[Cii].nHeight = rObj.nHeight; } } } for(VRectObj::size_type vx = 0; vx<vecRect.size(); vx++){ CenPoint.x = vecRect[vx].nx + (int)(0.5*vecRect[vx].nWidth); CenPoint.y = vecRect[vx].ny + (int)(0.5*vecRect[vx].nHeight); vecPoint.push_back(CenPoint); std::cout<<"Sort vecRect["<<vx<<"]:("<<vecRect[vx].nx<<","<<vecRect[vx].ny<<","; std::cout<<vecRect[vx].nWidth<<","<<vecRect[vx].nHeight<<")"; std::cout<<"["<<CenPoint.x <<","<<CenPoint.y << "]"<<std::endl; } double XDistance = 0.0; double YDistance = 0.0; double CDistance = 0.0; Point pt1,pt2,pt3,pt4; Point Tpt1,Tpt2,Tpt3,Tpt4; for(Ci =0; Ci<vecRect.size(); Ci++){ if((vecRect[Ci].nx !=0)&&(vecRect[Ci].ny !=0)&&(vecRect[Ci].nWidth !=0)&&(vecRect[Ci].nHeight !=0)){ pt1.x = vecRect[Ci].nx; pt1.y = vecRect[Ci].ny; pt2.x = vecRect[Ci].nx +vecRect[Ci].nWidth; pt2.y = vecRect[Ci].ny +vecRect[Ci].nHeight; for(Cii = 0;Cii <vecRect.size()&&(Cii !=Ci);Cii++){ if((vecRect[Cii].nx !=0)&&(vecRect[Cii].ny !=0)&&(vecRect[Cii].nWidth !=0)&&(vecRect[Cii].nHeight !=0)){ pt3.x = vecRect[Cii].nx; pt3.y = vecRect[Cii].ny; pt4.x = vecRect[Cii].nx +vecRect[Cii].nWidth; pt4.y = vecRect[Cii].ny +vecRect[Cii].nHeight; if(((pt1.x<=pt3.x)&&(pt4.x<=pt2.x)&&(pt1.y<=pt3.y)&&(pt4.y<=pt2.y))|| ((pt1.x>=pt3.x)&&(pt4.x>=pt2.x)&&(pt1.y>=pt3.y)&&(pt4.y>=pt2.y))){ if((vecRect[Ci].nWidth >vecRect[Cii].nWidth)&&(vecRect[Ci].nHeight >vecRect[Cii].nHeight)){ vecRect[Cii].nx =0; vecRect[Cii].ny =0; vecRect[Cii].nWidth =0; vecRect[Cii].nHeight =0; } if((vecRect[Ci].nWidth< vecRect[Cii].nWidth)&&(vecRect[Ci].nHeight < vecRect[Cii].nHeight)){ vecRect[Ci].nx =0; vecRect[Ci].ny =0; vecRect[Ci].nWidth =0; vecRect[Ci].nHeight =0; } } XDistance = abs(vecPoint[Ci].x -vecPoint[Cii].x); YDistance = abs(vecPoint[Ci].y -vecPoint[Cii].y); CDistance = sqrt(XDistance*XDistance+YDistance*YDistance); int ThrVal = cvDataMax(vecRect[Ci].nWidth,vecRect[Ci].nHeight,vecRect[Cii].nWidth,vecRect[Cii].nHeight); if(CDistance <= ThrVal){ Tpt1.x = cvDataMin(pt1.x,pt2.x,pt3.x,pt4.x); Tpt1.y = cvDataMin(pt1.y,pt2.y,pt3.y,pt4.y); Tpt2.x = cvDataMax(pt1.x,pt2.x,pt3.x,pt4.x); Tpt2.y = cvDataMax(pt1.y,pt2.y,pt3.y,pt4.y); if(Ci< Cii){ vecRect[Ci].nx = Tpt1.x; vecRect[Ci].ny = Tpt1.y; vecRect[Ci].nWidth = abs(Tpt2.x - Tpt1.x); vecRect[Ci].nHeight = abs(Tpt2.y - Tpt1.y); vecRect[Cii].nx = 0; vecRect[Cii].ny = 0; vecRect[Cii].nWidth = 0; vecRect[Cii].nHeight = 0; for(int i =0; i<10; i++){ cvMergeRect(vecRect,true); } } if(Ci>Cii){ vecRect[Cii].nx = Tpt1.x; vecRect[Cii].ny = Tpt1.y; vecRect[Cii].nWidth = abs(Tpt2.x - Tpt1.x); vecRect[Cii].nHeight = abs(Tpt2.y - Tpt1.y); vecRect[Ci].nx = 0; vecRect[Ci].ny = 0; vecRect[Ci].nWidth = 0; vecRect[Ci].nHeight = 0; for(int i =0; i<10; i++){ cvMergeRect(vecRect,true); } } } } }//Cii_for } } for( VRectObj::size_type ix =0; ix< vecRect.size(); ix++){ if((vecRect[ix].nx !=0)&&(vecRect[ix].ny !=0)&&(vecRect[ix].nWidth !=0)&&(vecRect[ix].nHeight !=0)){ vecRectResult.push_back(vecRect[ix]); } } }
关于Image Engineering& Computer Vision很多其它讨论与交流,敬请关注本博客和新浪微博songzi_tea.
非零点之间聚类
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。