图像分割简单处理

//学习OPENCV第5章,简单图像处理
#include<stdio.h>
#include<cv.h>
#include<highgui.h>
#include<stdio.h>
#include <opencv2/legacy/legacy.hpp>

void f(IplImage* src, IplImage* dst,int layer);
void sum_rgb(IplImage* src,IplImage* dst);
void sum_rgb1(IplImage* src,IplImage* dst); 

int main(int argc, char** argv)
{
	//-------------------------------------------------------------------
	//图像金字塔分割
	IplImage* src = cvLoadImage("D:\\AI_Proj\\OPENCV\\cameraman.tif");
	if(!src) 
	{ 
		printf("Couldn't seem to Open image, sorry\n"); 
		return -1;
	}
	
	//分别按照金字塔2/4/6层分割
	IplImage* dst2l = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
	IplImage* dst4 = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
	IplImage* dst6 = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
	f(src,dst2l,2);
	f(src,dst4,4);
	f(src,dst6,6);
	cvNamedWindow("PyrSegmentation2",1);
	cvNamedWindow("PyrSegmentation4",1);
	cvNamedWindow("PyrSegmentation6",1);
	cvShowImage("PyrSegmentation2",dst2l);
	cvShowImage("PyrSegmentation4",dst4);
	cvShowImage("PyrSegmentation6",dst6);
	
	while(1) 
	{ 
		if(cvWaitKey(100) == 27) 
			break; 
	}
	
	cvDestroyWindow("PyrSegmentation2");
	cvDestroyWindow("PyrSegmentation4");
	cvDestroyWindow("PyrSegmentation6");
	cvReleaseImage(&src);
	cvReleaseImage(&dst2l);
	cvReleaseImage(&dst4);
	cvReleaseImage(&dst6);
	cvWaitKey();
	
	//-------------------------------------------------------------------
	//rgb分离:加权加法得到目的图像
	IplImage* src1 = cvLoadImage("D:\\AI_Proj\\OPENCV\\dog.jpg");
	IplImage* dst1 = cvCreateImage(cvGetSize(src1),src1->depth,1);
	sum_rgb(src1,dst1);
	cvNamedWindow("split_rgb",1);
	cvShowImage("split_rgb",dst1);
	while(1) 
	{ 
		if((cvWaitKey(10)&0x7f) == 27) 
			break; 
	}
	
	cvDestroyWindow("split_rgb");
	cvReleaseImage(&src1);
	cvReleaseImage(&dst1);
	cvWaitKey();
	
	//-------------------------------------------------------------------
	//rgb分离:通过累加cvAcc得到目的图像
	IplImage* src2 = cvLoadImage("D:\\AI_Proj\\OPENCV\\dog.jpg");
	IplImage* dst2 = cvCreateImage(cvGetSize(src2),src2->depth,1);
	sum_rgb1(src2,dst2);
	cvNamedWindow("cvAcc_rgb",1);
	cvShowImage("cvAcc_rgb",dst2);
	
	while(1) 
	{ 
		if((cvWaitKey(10)&0x7f) == 27) 
			break; 
	}
	cvDestroyWindow("cvAcc_rgb");
	cvReleaseImage(&src2);
	cvReleaseImage(&dst2);
	
	cvWaitKey();
	
	//-------------------------------------------------------------------
	//自适应分割:增加可配性
	IplImage* Igray;
	IplImage* It;
	IplImage* Iat;
	if(!(Igray = cvLoadImage("D:\\AI_Proj\\OPENCV\\dog.jpg",CV_LOAD_IMAGE_GRAYSCALE)))
		return -1;

    double threshold = 100;//(double)atof(argv[1]);
    int threshold_type = CV_THRESH_BINARY;//atoi(argv[2]) ? CV_THRESH_BINARY : CV_THRESH_BINARY_INV;
    int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C;//atoi(argv[3]) ? CV_ADAPTIVE_THRESH_MEAN_C : CV_ADAPTIVE_THRESH_GAUSSIAN_C;
    int block_size = 3;//atoi(argv[4]);
    double offset = 0;//(double)atof(argv[5]);
    
	//Create the grayscale output images
    It = cvCreateImage(cvSize(Igray->width,Igray->height),IPL_DEPTH_8U,1);
    Iat = cvCreateImage(cvSize(Igray->width,Igray->height),IPL_DEPTH_8U,1);
    
	//Threshold
    cvThreshold(Igray,It,threshold,255,threshold_type);
	//根据block_size内像素,二值化
	//P159:只能处理8位图像,或浮点图像,源图像与目的图像不能一致。
    cvAdaptiveThreshold(Igray,Iat,255,adaptive_method,threshold_type,block_size,offset);
	
    //PUT UP 2 WINDOWS
    cvNamedWindow("Raw",1);
    cvNamedWindow("Threshold",1);
    cvNamedWindow("Adaptive_Threshold",1);
    //Show the results
    cvShowImage("Raw",Igray);
    cvShowImage("Threshold",It);
    cvShowImage("Adaptive_Threshold",Iat);
    cvWaitKey(0);
    //Clean up
    cvReleaseImage(&Igray);
    cvReleaseImage(&It);
    cvReleaseImage(&Iat);
	cvDestroyWindow("Raw");
	cvDestroyWindow("Threshold");
	cvDestroyWindow("Adaptive_Threshold");
	return(0);
}

//图像金字塔实现分割
void f(IplImage* src,IplImage* dst,int layer) 
{
	//为结构体CvMemStorage分配空间,返回指向该空间的指针
	CvMemStorage* storage = cvCreateMemStorage(0);
	//动态结构序列CvSeq是所有OpenCv动态数据结构的基础;有两种类型的序列:稠密序列,稀疏序列
	CvSeq* comp = NULL;
	
	//用金字塔实现图像分割P153
	//http://blog.csdn.net/cartoonface/article/details/5998543
	//参数:源/目的图像;存储连通部件的序列结果;分割部件的输出序列指针;
	//最大层数layer;阈值200,50
	cvPyrSegmentation(src,dst,storage,&comp,layer,200,50);
	int n_comp = comp->total;
	//对序列进行索引,或进行其他操作
	for(int i=0;i<n_comp;i++) 
	{
		//cvGetSeqElem返回索引指定元素的指针
		//comp是要检测的序列,而i是元素在序列中的索引
		CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem(comp,i);
		// do_something_with( cc );
	}
	cvReleaseMemStorage(&storage);
}

void sum_rgb(IplImage* src,IplImage* dst) 
{
	IplImage* r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	IplImage* g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	IplImage* b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	
	//Temporary storage.
	IplImage* s = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	//Split image onto the color planes.图像通道分离
	cvSplit(src,r,g,b,NULL);
		
	//Add equally weighted rgb values.
	//s=r*1/3+g*1/3
	//s=s*2/3+b*1/3
	//通常不对8位数组进行加法运算,可能溢出。
	//通过加权加法对3通道进行运算,高于100进行截断
	cvAddWeighted(r,1./3.,g,1./3.,0.0,s);
	cvAddWeighted(s,2./3.,b,1./3.,0.0,s);
	
	//对value大于100的像素进行截断为255,不足100的保留原值
	cvThreshold(s,dst,100,255,CV_THRESH_TRUNC);
	
	cvNamedWindow("split_r",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("split_g",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("split_b",CV_WINDOW_AUTOSIZE);
	cvNamedWindow("s",CV_WINDOW_AUTOSIZE);
	cvShowImage("split_r",r);
	cvShowImage("split_g",g);
	cvShowImage("split_b",b);
	cvShowImage("s",s);
	cvWaitKey();
	cvReleaseImage(&r);
	cvReleaseImage(&g);   
	cvReleaseImage(&b);   
	cvReleaseImage(&s);
	cvDestroyWindow("split_r");
	cvDestroyWindow("split_g");
	cvDestroyWindow("split_b");
	cvDestroyWindow("s");
}

void sum_rgb1(IplImage* src,IplImage* dst) 
{
	IplImage* r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	IplImage* g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	IplImage* b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
	
	IplImage* s = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);

	cvSplit(src,r,g,b,NULL);
	//图像累加
	cvZero(s);
	cvAcc(b,s);
	cvAcc(g,s);
	cvAcc(r,s);

	cvThreshold(s,s,100,255,CV_THRESH_TRUNC );
	//使用线性变换转换数组
	//源/目的图像;缩放因子;添加的值
	cvConvertScale(s,dst,1,0);
 
	cvReleaseImage(&r);
	cvReleaseImage(&g);   
	cvReleaseImage(&b);   
	cvReleaseImage(&s);
}


示例效果:

金字塔层数越多分割越模糊





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值