可选颜色(Selective Color)
可选颜色是Photoshop的常用图像调整功能。 可以选定某些颜色进行调整,而不影响其它颜色。
可选颜色功能常用于创造某种色调。
首先选取颜色,有9种: 红、黄、绿、青、蓝、洋红、白、中性色、黑
然后,可以调整该颜色的 : 青、洋红、黄、黑 组成要素。
调整方法可以选择 相对 或 绝对 两种。
(一)可选颜色的原理
要了解相关原理
(二)OpenCV实现
1,我用OpenCV 编写了一个 SelectiveColor 类,实现可选颜色调整。在源文件 SelectiveColor.hpp, SelectiveColor.cpp中
3, 使用方法: SelectiveColor类有一个属性colors[9], 定义了9个颜色通道(红、黄、绿、青、蓝、洋红、白、中性色、黑)。
每个颜色通道有cyan, magenta, yellow, black 四个值。设置好所需通道和值,再调用SelectiveColor类的adjust()方法即可对图像进行 可选颜色调整。
(三)例程
使用SelectiveColor类,进行可选颜色调整。
1 #include <cstdio>
2 #include <iostream>
3 #include "opencv2/core.hpp"
4 #include "opencv2/imgproc.hpp"
5 #include "opencv2/highgui.hpp"
6
7 #include "SelectiveColor.hpp"
8
9 using namespace std;
10 using namespace cv;
11
12 static string window_name = "Photo";
13 static Mat src;
14
15 static Mat adjust_mat;
16 static string adjust_window = "Selective Color";
17 static int color = 2;
18 SelectiveColor selectiveColor;
19
20 vector<Point> points;
21
22 int cyan;
23 int magenta;
24 int yellow;
25 int black;
26 int is_absolute;
27
28 static void invalidate()
29 {
30 Mat dst;
31 selectiveColor.adjust(src, dst);
32
33 imshow(window_name, dst);
34 imshow(adjust_window, adjust_mat);
35 }
36
37 static void channelRead(int which)
38 {
39 color = which;
40
41 SelectiveColorAdjust * current = NULL;
42 if ( color >=0 && color <= 9)
43 current = &(selectiveColor.colors[color]);
44 if ( current == NULL ) return;
45
46 cyan = (current->cyan < 0) ? (current->cyan + 1) * 100 : current->cyan * 100;
47 magenta = (current->magenta < 0) ? (current->magenta + 1) * 100 : current->magenta * 100;
48 yellow = (current->yellow < 0) ? (current->yellow + 1) * 100 : current->yellow * 100;
49 black = (current->black < 0) ? (current->black + 1) * 100 : current->black * 100;
50
51 if ( selectiveColor.isAbsolute )
52 is_absolute = 1;
53 else
54 is_absolute = 0;
55
56 }
57
58 static void channelWrite()
59 {
60 SelectiveColorAdjust * current = NULL;
61 if ( color >=0 && color <= 9)
62 current = &(selectiveColor.colors[color]);
63 if ( current == NULL ) return;
64
65 current->cyan = (cyan - 100 ) / 100.0;
66 current->magenta = (magenta - 100 ) / 100.0;
67 current->yellow = (yellow - 100 ) / 100.0;
68 current->black = (black - 100 ) / 100.0;
69
70 selectiveColor.isAbsolute = ( is_absolute == 1 );
71 invalidate();
72 }
73
74
75 static void callbackAdjust(int , void *)
76 {
77 channelWrite();
78 invalidate();
79 }
80
81
82 static void callbackAdjustChannel(int , void *)
83 {
84 channelRead(color);
85 setTrackbarPos("cyan", adjust_window, cyan);
86 setTrackbarPos("magenta", adjust_window, magenta);
87 setTrackbarPos("yellow", adjust_window, yellow);
88 setTrackbarPos("black", adjust_window, black);
89 setTrackbarPos("Absolute", adjust_window, is_absolute);
90 invalidate();
91 }
92
93 static void callbackMouseEvent(int mouseEvent, int x, int y, int flags, void* param)
94 {
95 switch(mouseEvent) {
96 case CV_EVENT_LBUTTONDOWN:
97 break;
98 case CV_EVENT_MOUSEMOVE:
99 break;
100 case CV_EVENT_LBUTTONUP:
101 points.push_back(Point(x, y));
102 invalidate();
103 break;
104 case CV_EVENT_LBUTTONDBLCLK:
105 points.clear();
106 invalidate();
107 break;
108 }
109 return;
110 }
111
112 int main()
113 {
114 //read image file
115 src = imread("building.jpg");
116 if ( !src.data ) {
117 cout << "error read image" << endl;
118 return -1;
119 }
120
121 //create window
122 namedWindow(window_name);
123 imshow(window_name, src);
124 setMouseCallback(window_name, callbackMouseEvent, NULL );
125
126
127 //create window for levels
128 namedWindow(adjust_window);
129 adjust_mat = Mat::ones(100,400, CV_8UC3);
130 adjust_mat.setTo( Scalar(255,255,255) );
131 imshow(adjust_window, adjust_mat);
132
133 channelRead(0);
134 createTrackbar("Color", adjust_window, &color, 8, callbackAdjustChannel);
135 createTrackbar("cyan", adjust_window, &cyan, 200, callbackAdjust);
136 createTrackbar("magenta", adjust_window, &magenta, 200, callbackAdjust);
137 createTrackbar("yellow", adjust_window, &yellow, 200, callbackAdjust);
138 createTrackbar("black", adjust_window, &black, 200, callbackAdjust);
139 createTrackbar("Absolute", adjust_window, &is_absolute, 1, callbackAdjust);
140
141 waitKey();
142 return 0;
143 }
运行效果:
原图:
对红色 (color = 0 ), 进行调整后