简介
本篇是使用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);
}
效果演示
对应的效果演示如下: