图像分割

28 篇文章 1 订阅
23 篇文章 2 订阅

图像分割

1.基于金字塔的方法

//输入:src-原始彩色图像
void gray_segmentation(IplImage * src,IplImage *dst)
{
	parameters initialization//  
	int mode = CV_RETR_LIST;  
	int level = 2, block_size = 1000;  
	CvMemStorage* storage = cvCreateMemStorage(block_size);  
	CvSeq* components;  
	double threshold1 = 100,threshold2 = 50;  

	IplImage *image = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);  
	cvCvtColor(src,image,CV_RGB2GRAY);  
	

	image->width = dst->width = (src->width & -(1 << level));  
	image->height = dst->height = (src->height & -(1 << level));  

	//Segment/  
	cvPyrSegmentation(image,dst,storage,&components,level,threshold1,threshold2);  
	int ncomp = components->total;  
	cout<<"segemented into "<<ncomp<<" components."<<endl;  

	//Get Components/    
	for (int i = 0; i < ncomp; i++)//foreach connection component  
	{  
		CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem(components,i);  
		cvDrawRect(dst,cvPoint(cc->rect.x,cc->rect.y),cvPoint(cc->rect.x+cc->rect.width,cc->rect.y+cc->rect.height),cvScalar(0,0,0));  
	}  
	cvReleaseMemStorage(&storage); 

	cvReleaseImage(&image);
}


//
//输入:src-原始彩色图像
//		dst- 空
//
void rgb_segmentation(IplImage * src,IplImage *dst)
{
	parameters initialization//  
	int mode = CV_RETR_LIST;  
	int level = 2, block_size = 1000;  
	CvMemStorage* storage = cvCreateMemStorage(block_size);  
	CvSeq* components;  
	double threshold1 = 10,threshold2 = 50;  

	IplImage *image = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);  
	image = cvCloneImage(src);    

	image->width = dst->width = (src->width & -(1 << level));  
	image->height = dst->height = (src->height & -(1 << level));  

	//Segment/  
	cvPyrSegmentation(image,dst,storage,&components,level,threshold1,threshold2);  
	int ncomp = components->total;  

	//Get Components/    
	for (int i = 0; i < ncomp; i++)//foreach connection component  
	{  
		CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem(components,i);  
		cvDrawRect(dst,cvPoint(cc->rect.x,cc->rect.y),cvPoint(cc->rect.x+cc->rect.width,cc->rect.y+cc->rect.height),cvScalar(255,0,0));  
	}  

	cvReleaseImage(&image);
	cvReleaseMemStorage(&storage);  
}

2.基于边缘的方法

//
//基于边缘检测进行图像分割
//输入:src- 原始图像
//		dst-原始图像
//返回:dst -分割结果
//		1- 输入为空
//		2-
int seg_base_edge(IplImage * src,IplImage * dst)
{
	if(NULL == src || NULL == dst){
		return 1;
	}
	//获取灰度图片
	IplImage * pGrayImg = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	cvCvtColor(src,pGrayImg,CV_BGR2GRAY);
	//利用Canny算子进行边缘检测
	IplImage * pCannyImg = cvCreateImage(cvGetSize(pGrayImg),pGrayImg->depth,pGrayImg->nChannels);
	cvCanny(pGrayImg,pCannyImg,50,150,3);

	//膨胀,使边缘轮廓闭合
	IplImage * pDilateImg = cvCreateImage(cvGetSize(pGrayImg),pGrayImg->depth,1);
	IplConvKernel *rect_2;
	rect_2 = cvCreateStructuringElementEx(2, 3, 1, 1, CV_SHAPE_RECT);
	cvDilate(pCannyImg, pDilateImg);

	//检测图片轮廓
	CvMemStorage * storage = cvCreateMemStorage(0);
	CvSeq * contour = 0;
	int mode = CV_RETR_EXTERNAL;
	int num = cvFindContours(pDilateImg,storage,&contour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_NONE, cvPoint(0,0) );

	//用白色填充面积最大的轮廓
	double maxArea = 1000;
	IplImage * pContourImg = cvCreateImage(cvGetSize(pCannyImg), IPL_DEPTH_8U, 3);
	//初始化为黑色
	cvZero(pContourImg);
	while(contour)
	{
		double area = fabs(cvContourArea(contour, CV_WHOLE_SEQ));
		if(area > maxArea)
		{
			cvDrawContours(pContourImg,contour,cvScalarAll(255),cvScalarAll(0),0,CV_FILLED);
		}
		contour = contour->h_next;
	}
	cvReleaseMemStorage(&storage);

	//填充图作为mask,与原图像进行按像素与操作
	for(int height = 0; height < src->height;height++){
		for(int width = 0; width < src->width; width++)
		{
			int piex = height * src->width + width;
			if((BYTE)pContourImg->imageData[piex * 3] != 255u)
			{
				dst->imageData[piex * 3] = 0;
				dst->imageData[piex * 3 + 1] = 0;
				dst->imageData[piex * 3 + 2] = 0;
			}
		}
	}

	//释放资源
	cvReleaseImage(&pGrayImg);
	cvReleaseImage(&pCannyImg);
	cvReleaseImage(&pDilateImg);
	cvReleaseImage(&pContourImg);

	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值