您的位置:首页 > 编程语言

OpenCV编程->OpenMP优化入门

2014-04-13 21:14 423 查看
找了个去雾源码,做了简单的优化:
IplImage *quw1(IplImage *src,int block,double w) { 	//图像分别有三个颜色通道 	IplImage *dst1=NULL; 	IplImage *dst2=NULL; 	IplImage *dst3=NULL; 	IplImage *imgroi1; 	//dst1的ROI 	IplImage *imgroi2; 	//dst2的ROI 	IplImage *imgroi3; 	//dst3的ROI 	IplImage *roidark; 	//dark channel的ROI 	IplImage *dark_channel=NULL; 	//暗原色先验的指针 	IplImage *toushelv=NULL; 	//透射率  	//去雾算法运算后的三个通道 	IplImage *j1=NULL; 	IplImage *j2=NULL; 	IplImage *j3=NULL; 	//去雾后的图像,三通道合并成 	IplImage *dst=NULL; 	//源图像ROI位置以及大小 	CvRect ROI_rect;  	//分离的三个通道 	dst1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 	dst2=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 	dst3=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  	//为各个ROI分配内存 	imgroi1=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1); 	imgroi2=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1); 	imgroi3=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1); 	roidark=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);  	//为j1 j2 j3分配大小 	j1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 	j2=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 	j3=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  	//为暗原色先验指针分配大小 	dark_channel=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 	//为透射率指针分配大小 	toushelv=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1); 	//dst分配大小 	dst=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,3); 	//将原彩色图像分离成三通道 	cvSplit(src,dst1,dst2,dst3,NULL); 	//求暗原色 	ROI_rect.width=block; 	ROI_rect.height=block; 	ROI_rect.x=0; 	ROI_rect.y=0;   	int i; 	int j; 	double min1=0; 	double max1=0; 	double min2=0; 	double max2=0; 	double min3=0; 	double max3=0; 	double min=0; 	CvScalar value;  #pragma omp parallel for 	for(i=0;i<src->width/block;i++) 	{         		for(j=0;j<src->height/block;j++) 		{ 			//分别计算三个通道内ROI的最小值 			cvSetImageROI(dst1,ROI_rect); 			cvCopy(dst1,imgroi1,NULL); 			cvMinMaxLoc(imgroi1,&min1,&max1,NULL,NULL);  			cvSetImageROI(dst2,ROI_rect); 			cvCopy(dst2,imgroi2,NULL); 			cvMinMaxLoc(imgroi2,&min2,&max2,NULL,NULL);  			cvSetImageROI(dst3,ROI_rect); 			cvCopy(dst3,imgroi3,NULL); 			cvMinMaxLoc(imgroi3,&min3,&max3,NULL,NULL); 			//求三个通道内最小值的最小值; 			if(min1<min2) 				min=min1; 			else 				min=min2; 			if(min>min3) 				min=min3;//min为这个ROI中暗原色 			value=cvScalar(min,min,min,min);//min放在value中;  			//min赋予dark_channel中相应的ROI; 			cvSetImageROI(dark_channel,ROI_rect); 			cvSet(roidark,value,NULL); 			cvCopy(roidark,dark_channel,NULL); 			//释放各个ROI; 			cvResetImageROI(dst1); 			cvResetImageROI(dst2); 			cvResetImageROI(dst3); 			cvResetImageROI(dark_channel); 			//转入下一个ROI 			ROI_rect.x=block*i; 			ROI_rect.y=block*j; 		} 	} 	//保存暗原色先验的图像 	cvSaveImage("D:/dark_channel_prior.jpg",dark_channel); 	//利用得到的暗原色先验dark_channel_prior.jpg求大气光强 	double min_dark; 	double max_dark; 	CvPoint min_loc; 	CvPoint max_loc; 	//max_loc是暗原色先验最亮一小块的原坐标 	cvMinMaxLoc(dark_channel,&min_dark,&max_dark,&min_loc,&max_loc,NULL); 	//	cout<<max_loc.x<<" "<<max_loc.y<<endl; 	ROI_rect.x=max_loc.x; 	ROI_rect.y=max_loc.y; 	double A_dst1;//定义大气光成分的估计值 	double dst1_min; 	double A_dst2; 	double dst2_min; 	double A_dst3; 	double dst3_min;  	cvSetImageROI(dst1,ROI_rect); 	//按照论文方法求大气光强估计值 	cvCopy(dst1,imgroi1,NULL); 	cvMinMaxLoc(imgroi1,&dst1_min,&A_dst1,NULL,NULL);  	cvSetImageROI(dst2,ROI_rect); 	cvCopy(dst2,imgroi2,NULL); 	cvMinMaxLoc(imgroi2,&dst2_min,&A_dst2,NULL,NULL);  	cvSetImageROI(dst3,ROI_rect); 	cvCopy(dst3,imgroi3,NULL); 	cvMinMaxLoc(imgroi3,&dst3_min,&A_dst3,NULL,NULL); 	//	cout<<A_dst1<<" "<<A_dst2<<" "<<A_dst3<<endl;//这三值为大气光强度估计值 	//求透射率 	int k; 	int l; 	CvScalar m; 	CvScalar n;//暗原色先验各元素值 #pragma omp parallel for 	for(k=0;k<src->height;k++) 	{ 		for(l=0;l<src->width;l++) 		{ 			m=cvGet2D(dark_channel,k,l); 			n=cvScalar(255-w*m.val[0]); 			//w目的是保留一部分的雾,使图像看起来真实些 			cvSet2D(toushelv,k,l,n); 		} 	} 	cvSaveImage("D:/toushelv.jpg",toushelv);  	//求无雾图像 	int p,q; 	double tx; 	double jj1,jj2,jj3; 	CvScalar ix,jx; #pragma omp parallel for 	for(p=0;p<src->height;p++) 	{ 		for(q=0;q<src->width;q++) 		{ 			tx=cvGetReal2D(toushelv,p,q); 			tx=tx/255; 			if(tx<0.1) 				tx=0.1; 			ix=cvGet2D(src,p,q); 			jj1=(ix.val[0]-A_dst1)/tx+A_dst1;//根据雾产生模型运算,还原出无雾图像 			jj2=(ix.val[1]-A_dst2)/tx+A_dst2; 			jj3=(ix.val[2]-A_dst3)/tx+A_dst3; 			jx=cvScalar(jj1,jj2,jj3,0.0); 			cvSet2D(dst,p,q,jx); 		} 	} 	cvSaveImage("3.jpg",dst);  	//释放指针 	cvReleaseImage(&dst1); 	cvReleaseImage(&dst2); 	cvReleaseImage(&dst3); 	cvReleaseImage(&imgroi1); 	cvReleaseImage(&imgroi2); 	cvReleaseImage(&imgroi3); 	cvReleaseImage(&roidark); 	cvReleaseImage(&dark_channel); 	cvReleaseImage(&toushelv); 	cvReleaseImage(&j1); 	cvReleaseImage(&j2); 	cvReleaseImage(&j3); 	return dst; }
编译运行后:



得到结果如下:



其实上面的代码还可以再优化:
三通道可以分配三个线程分别计算,然后同步再做计算,应该效果会更好,本人的计算机就个双核,所以优势也体现不出来,就没做过多的优化了,就当入门。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: