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);
}

效果演示

  对应的效果演示如下:
        
时间: 2024-07-31 21:05:42

opencv实现图像优化的相关文章

OpenCV中图像的结构和区别

在OpenCV中,现在有很多种结构类型可以用来表示图像,它们之间有区别又有联系,现在记录一下它们之间的区别和相似之处,以便后面查看. 其中类型有: 1. Iplimage,2. Mat,3.CvMat, 4.CVArr: 其中: 1. IplImage: 较老版本的图像存储类型,在2.0之前使用: 2. CvArr: 也是较老的一种存储结构,是一种抽象的基类. 3. CvMat: 矩阵结构. 4. Mat:  新版本中使用的,推荐使用,是一个图像容器,基本上讲 Mat 是一个类,由两个数据部分组

opencv对图像进行边缘及角点检测

opencv对图像进行边缘及角点检测 先看结果: 代码: // ConsoleApplication1_812.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "opencv2/opencv.hpp" class Imagedetector{ public: Imagedetector():threshold(-1) ,cross(5

用opencv读取图像鼠标点的像素,更正一个Bug

作者:skyseraph 出处:http://www.cnblogs.com/skyseraph/ 以下代码在网上流传很广. 不过,调试运行之后发现,功能是正确的,但是内存很快就耗尽,导致死机.经过查找,加上: cvReleaseImage(&img1);    //释放源图像占用的内存 这一行是我(szliug)加的,否则内存很快就会耗尽,会死机的. 之后运行正常. /*===============================================// 功能:OpenCV Ut

实验2014062701:opencv对图像的点操作

#include<Windows.h>#include<cv.h>#include<highgui.h>#include <cxcore.h>int main(){    IplImage* img = cvLoadImage("1.jpg");    IplImage* dst = cvCreateImage(cvGetSize(img),img->depth,1);    cvNamedWindow("GRAY&quo

OpenCV中图像算术操作与逻辑操作

OpenCV中图像算术操作与逻辑操作 在图像处理中有两类最重要的基础操作分别是图像点操作与块操作,简单点说图像点操作就是图像每个像素点的相关逻辑与几何运算.块操作最常见就是基于卷积算子的各种操作.实现各种不同的功能.今天小编就跟大家一起学习OpenCV中图像点操作相关的函数与应用场景.常见算术运算包括加.减.乘.除,逻辑运算包括与.或.非.异或.准备工作: 选择两张大小一致的图像如下.加载成功以后显示如下: 加法操作结果如下: 减法操作结果如下: 乘法操作结果如下: 除法操作结果如下: 权重加法

【opencv】图像细化

[opencv]图像细化 [opencv]图像细化 2014-02-17 21:03 5404人阅读 评论(14) 收藏 举报  分类: opencv(1)  版权声明:本文为博主原创文章,未经博主允许不得转载. 在我们进行图像处理的时候,有可能需要对图像进行细化,提取出图像的骨架信息,进行更加有效的分析. 图像细化(Image Thinning),一般指二值图像的骨架化(Image Skeletonization) 的一种操作运算. 所谓的细化就是经过一层层的剥离,从原来的图中去掉一些点,但仍

OpenCV实现图像亮区扩张

纯粹阅读,移步OpenCV实现图像亮区扩张 效果图 源码 KqwOpenCVBlurDemo 亮区扩张,也叫膨胀,要实现这样的效果,我们可以选取一个合适大小的核,用被核覆盖的最大值代替锚点像素.膨胀可以用来融合可能被分割的目标. 我们首先定义一个合适大小的核 Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)); 然后调用Imgproc.dilate()方法把图像的亮区放大 //

OpenCV实现图像暗区扩张(腐蚀图片)

纯粹阅读,请移步OpenCV实现图像暗区扩张(腐蚀图片) 效果图 源码 KqwOpenCVBlurDemo 暗区扩张,也叫腐蚀,要实现这样的效果,我们可以选取一个合适大小的核,用被核覆盖的最小值代替锚点像素. 我们首先定义一个合适大小的核 Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)); 然后调用Imgproc.erode()方法把图像的暗区放大 // 扩大暗区(腐蚀)

OpenCV实现图像阈值化

纯粹阅读,请移步OpenCV实现图像阈值化 效果图 源码 KqwOpenCVBlurDemo 阈值化是一种将我们想要在图像中分析的区域分割出来的方法. 我们把每个像素值都与一个预设的阈值做比较,再根据比较的结果调整像素值. 类似这样 Imgproc.threshold(src,src,100,255,Imgproc.THRESH_BINARY); 其中100是阈值,255是最大值(纯白色的值). 常量 名称 常量 二值阈值化 Imgproc.THRESH_BINARY 阈值化到零 Imgproc