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()方法即可对图像进行  可选颜色调整。

(三)例程

使用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 ), 进行调整后

原文地址:https://www.cnblogs.com/ybqjymy/p/13801383.html