本篇是使用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); }
对应的效果演示如下:
原文地址:http://blog.csdn.net/u011630458/article/details/46224603