opencv实现图像优化

简介

  本篇是使用opencv实现,对图像亮度、对比度、锐化、白平衡和饱和度的调整。

具体实现

总体框架

  1、首先是打开需要调整的图片到src中,接着创建了一张新图片src2,将对对象编辑的所有bar,绑定到src2中。接着循环等待用户操作。 
如果用户按下'q',则退出程序;用户按下's',则保存当前图片到新文件中。
        memcpy(pic_name,argv[1],sizeof(argv[1]));
 
	src=cv::imread(pic_name,1);
	width = src.rows;
	height = src.cols;
	src2 = cv::Mat(src2_width, src2_height, CV_8UC3, 1);
	cv::imshow("src",src);
	cv::imshow(barPic, src2);
	createTrackbar("light", barPic, &light_num, light_max, light_trackbar);
	createTrackbar("contrast", barPic, &contrast_num, contrast_max, contrast_trackbar);
	createTrackbar("sharpen", barPic, &sharpen_num, sharpen_max, sharpen_trackbar);
	createTrackbar("R_balance", barPic, &R_num, R_max, R_trackbar);
	createTrackbar("B_balance", barPic, &B_num, B_max, B_trackbar);
	createTrackbar("saturation", barPic, &saturation_num, saturation_max, saturation_trackbar);
 
	while(!exit){
		c = cv::waitKey(0);
		if(c == 'q'){
			exit = true;	
		}else if(c == 's'){
			imwrite("newfile.jpg", src);	
		}
	}
	cvDestroyAllWindows();

亮度

  首先判断上一个操作是不是也为亮度操作,如果不是则首先将当前文件保存到临时文件pic_tmp,用标志位flag[0]做具体判断。接着读出文件pic_tmp,
对该文件做亮度优化。根据拉动bar得到变化的亮度优化强度:light_now。然后整个图片都加上该亮度。
void light_trackbar(int pos, void *){
	IplImage pI_1;
	CvScalar s1;
	int light_now = light_num - 50;
	int i, j;
 
	if(flag[0] == false){
		imwrite(pic_tmp, src);
		for(i=0; i< bar_num; i++){
			flag[i] = false;		
		}
	}
	src=cv::imread(pic_tmp,1);
	flag[0] = true;
	pI_1 = src;
 
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[0] = s1.val[0] + light_now;
			s1.val[1] = s1.val[1] + light_now;
			s1.val[2] = s1.val[2] + light_now;
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	cv::imshow("src",src);
}

对比度

  1、根据flag[1],检查上次是不是也为对比度操作,如果不是,也首先保存当前图片到pic_tmp中,然后再读取出pic_tmp图片,进行后续操作。
根据对应的bar操作,计算出对比度增强强度,然后整个图片都乘上该对比度强度。
void contrast_trackbar(int pos, void *){
	IplImage pI_1;
	CvScalar s1;
	double contrast_now = ((double)contrast_num / 10);
	int i, j;
 
	if(flag[1] == false){
		imwrite(pic_tmp, src);
		for(i=0; i< bar_num; i++){
			flag[i] = false;		
		}
	}
	src=cv::imread(pic_tmp, 1);
	flag[1] = true;
	pI_1 = src;
 
	contrast_now = 0.5 + contrast_now / 2;
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[0] = s1.val[0] * contrast_now;
			s1.val[1] = s1.val[1] * contrast_now;
			s1.val[2] = s1.val[2] * contrast_now;
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	imshow("src",src);
}

锐度

  同样首先利用flag做判断,接着首先复制一份操作图片,将它模糊掉之后,和原图像相减。获得的图像差值再和当前处理图像相加,从而达到
锐化效果。
void sharpen_trackbar(int pos, void *){
	Mat src2;
	Mat src3 = cv::Mat(width, height, CV_8UC3, 1);;
	IplImage pI_1;
	IplImage pI_2, pI_3;
	CvScalar s1, s2;
	int sharpen_now = sharpen_num;
	int i, j;
 
	if(flag[2] == false){
		imwrite(pic_tmp, src);
		for(i=0; i< bar_num; i++){
			flag[i] = false;		
		}
	}
	src = cv::imread(pic_tmp, 1);
	src2 = cv::imread(pic_tmp, 1);
	flag[2] = true;
	pI_1 = src;
 
	pI_2 = src2;
	pI_3 = src3;
	if(sharpen_now%2 ==0){
		sharpen_now += 1;
	}
	cvSmooth(&pI_2, &pI_3, CV_GAUSSIAN, sharpen_now);
 
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_2, i, j);
			s2 = cvGet2D(&pI_3, i, j);
			s1.val[0] = s1.val[0] - s2.val[0];
			s1.val[1] = s1.val[1] - s2.val[1];
			s1.val[2] = s1.val[2] - s2.val[2];
			cvSet2D(&pI_2, i, j, s1);
		}
	}
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s2 = cvGet2D(&pI_2, i, j);
			s1.val[0] = s1.val[0] + s2.val[0];
			s1.val[1] = s1.val[1] + s2.val[1];
			s1.val[2] = s1.val[2] + s2.val[2];
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	imshow("src",src);
}

白平衡

  这里的白平衡,只是在原图像基础上,简单的根据用户bar拖动操作,增减对应的R和B分量。
void R_trackbar(int pos, void *){
	int R_now = R_num - 100;
	IplImage pI_1;
	CvScalar s1;
	int i, j;
 
	if(flag[3] == false){
		imwrite(pic_tmp, src);
		for(i=0; i< bar_num; i++){
			flag[i] = false;		
		}
	}
	src=cv::imread(pic_tmp, 1);
	flag[3] = true;
 
	pI_1 = src;
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[2] = s1.val[2] + R_now;
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	imshow("src",src);
}
 
void B_trackbar(int pos, void *){
	int B_now = B_num - 100;
	IplImage pI_1;
	CvScalar s1;
	int i, j;
 
	if(flag[4] == false){
		imwrite(pic_tmp, src);
		for(i=0; i< bar_num; i++){
			flag[i] = false;		
		}
	}
	src=cv::imread(pic_tmp, 1);
	flag[4] = true;
	pI_1 = src;
 
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[0] = s1.val[0] + B_now;
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	imshow("src",src);
}

饱和度

  首先将RGB图像转化为HSV,然后根据用户对应的bar操作,对S分量进行增减。最后将图像重新转换回RBG格式。
void saturation_trackbar(int pos, void *){
	int saturation_now = saturation_num - 50;
	IplImage pI_1;
	CvScalar s1;
	int i, j;
 
	if(flag[5] == false){
		imwrite(pic_tmp, src);
		for(i=0; i< bar_num; i++){
			flag[i] = false;
		}
	}
	src=cv::imread(pic_tmp, 1);
	flag[5] = true;
	pI_1 = src;
 
	cvCvtColor(&pI_1, &pI_1, CV_BGR2HSV);
	for(i=0; i<width; i++){
		for(j=0; j<height; j++){
			s1 = cvGet2D(&pI_1, i, j);
			s1.val[1] = s1.val[1] + saturation_now;
			cvSet2D(&pI_1, i, j, s1);
		}
	}
	cvCvtColor(&pI_1, &pI_1, CV_HSV2BGR);
	imshow("src",src);
}

效果演示

  对应的效果演示如下:
        

你可能感兴趣的:(opencv,图形图像)