系列文章:
用OpenCV实现Photoshop算法(四): 色阶调整用OpenCV实现Photoshop算法(五): 亮度对比度调整
用OpenCV实现Photoshop算法(六): 变为黑白图像
用OpenCV实现Photoshop算法(七): 调整色相饱和度
用OpenCV实现Photoshop算法(九): 高反差保留
八、可选颜色(Selective Color)
可选颜色是Photoshop的常用图像调整功能。 可以选定某些颜色进行调整,而不影响其它颜色。
可选颜色功能常用于创造某种色调。
首先选取颜色,有9种: 红、黄、绿、青、蓝、洋红、白、中性色、黑
然后,可以调整该颜色的 : 青、洋红、黄、黑 组成要素。
调整方法可以选择 相对 或 绝对 两种。
(一)可选颜色的原理
要了解相关原理,请参照这个博文: 关于可选颜色的计算公式
(二)OpenCV实现
1,我用OpenCV 编写了一个 SelectiveColor 类,实现可选颜色调整。在源文件 SelectiveColor.hpp, SelectiveColor.cpp中
3, 使用方法: SelectiveColor类有一个属性colors[9], 定义了9个颜色通道(红、黄、绿、青、蓝、洋红、白、中性色、黑)。
每个颜色通道有cyan, magenta, yellow, black 四个值。设置好所需通道和值,再调用SelectiveColor类的adjust()方法即可对图像进行 可选颜色调整。
4, 源文件及例程源码下载在这里: 可选颜色源码
(三)例程
使用SelectiveColor类,进行可选颜色调整。
- #include
- #include
- #include "opencv2/core.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/highgui.hpp"
-
- #include "SelectiveColor.hpp"
-
- using namespace std;
- using namespace cv;
-
- static string window_name = "Photo";
- static Mat src;
-
- static Mat adjust_mat;
- static string adjust_window = "Selective Color";
- static int color = 2;
- SelectiveColor selectiveColor;
-
- vector
points; -
- int cyan;
- int magenta;
- int yellow;
- int black;
- int is_absolute;
-
- static void invalidate()
- {
- Mat dst;
- selectiveColor.adjust(src, dst);
-
- imshow(window_name, dst);
- imshow(adjust_window, adjust_mat);
- }
-
- static void channelRead(int which)
- {
- color = which;
-
- SelectiveColorAdjust * current = NULL;
- if ( color >=0 && color <= 9)
- current = &(selectiveColor.colors[color]);
- if ( current == NULL ) return;
-
- cyan = (current->cyan < 0) ? (current->cyan + 1) * 100 : current->cyan * 100;
- magenta = (current->magenta < 0) ? (current->magenta + 1) * 100 : current->magenta * 100;
- yellow = (current->yellow < 0) ? (current->yellow + 1) * 100 : current->yellow * 100;
- black = (current->black < 0) ? (current->black + 1) * 100 : current->black * 100;
-
- if ( selectiveColor.isAbsolute )
- is_absolute = 1;
- else
- is_absolute = 0;
-
- }
-
- static void channelWrite()
- {
- SelectiveColorAdjust * current = NULL;
- if ( color >=0 && color <= 9)
- current = &(selectiveColor.colors[color]);
- if ( current == NULL ) return;
-
- current->cyan = (cyan - 100 ) / 100.0;
- current->magenta = (magenta - 100 ) / 100.0;
- current->yellow = (yellow - 100 ) / 100.0;
- current->black = (black - 100 ) / 100.0;
-
- selectiveColor.isAbsolute = ( is_absolute == 1 );
- invalidate();
- }
-
-
- static void callbackAdjust(int , void *)
- {
- channelWrite();
- invalidate();
- }
-
-
- static void callbackAdjustChannel(int , void *)
- {
- channelRead(color);
- setTrackbarPos("cyan", adjust_window, cyan);
- setTrackbarPos("magenta", adjust_window, magenta);
- setTrackbarPos("yellow", adjust_window, yellow);
- setTrackbarPos("black", adjust_window, black);
- setTrackbarPos("Absolute", adjust_window, is_absolute);
- invalidate();
- }
-
- static void callbackMouseEvent(int mouseEvent, int x, int y, int flags, void* param)
- {
- switch(mouseEvent) {
- case CV_EVENT_LBUTTONDOWN:
- break;
- case CV_EVENT_MOUSEMOVE:
- break;
- case CV_EVENT_LBUTTONUP:
- points.push_back(Point(x, y));
- invalidate();
- break;
- case CV_EVENT_LBUTTONDBLCLK:
- points.clear();
- invalidate();
- break;
- }
- return;
- }
-
- int main()
- {
- //read image file
- src = imread("building.jpg");
- if ( !src.data ) {
- cout << "error read image" << endl;
- return -1;
- }
-
- //create window
- namedWindow(window_name);
- imshow(window_name, src);
- setMouseCallback(window_name, callbackMouseEvent, NULL );
-
-
- //create window for levels
- namedWindow(adjust_window);
- adjust_mat = Mat::ones(100,400, CV_8UC3);
- adjust_mat.setTo( Scalar(255,255,255) );
- imshow(adjust_window, adjust_mat);
-
- channelRead(0);
- createTrackbar("Color", adjust_window, &color, 8, callbackAdjustChannel);
- createTrackbar("cyan", adjust_window, &cyan, 200, callbackAdjust);
- createTrackbar("magenta", adjust_window, &magenta, 200, callbackAdjust);
- createTrackbar("yellow", adjust_window, &yellow, 200, callbackAdjust);
- createTrackbar("black", adjust_window, &black, 200, callbackAdjust);
- createTrackbar("Absolute", adjust_window, &is_absolute, 1, callbackAdjust);
-
- waitKey();
- return 0;
- }
运行效果:
原图:
对红色 (color = 0 ), 进行调整后
评论记录:
回复评论: