zoukankan      html  css  js  c++  java
  • 非零点之间聚类

    在二值图像中,非零点之间的进行聚类,使用矩形框进行标记其区域过程中,主要解决相邻的两个矩形框之间重叠区域和嵌套现象。仅作參考.(注:因开发周期仅仅有几个小时的时间.代码有不规范地方,请各位见谅).

    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(...).
    ");
    		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.


  • 相关阅读:
    如何用nodejs创建一个proxy 服务
    企业包分发-应用内安装时碰到的问题
    React-Native与Weex的比较
    前端炫酷动画展示利器(lottie)
    记录一个web开发工具集网页
    git 和 远程分支关联
    reference to 'X' is ambiguous 解决
    mac 下解压 .bin文件
    fabric 集成trello
    ES6 对象的创建及操作
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3946152.html
Copyright © 2011-2022 走看看