用OpenCV实现Photoshop算法(八): 可选颜色

系列文章:

用OpenCV实现Photoshop算法(一): 图像旋转

用OpenCV实现Photoshop算法(二): 图像剪切

用OpenCV实现Photoshop算法(三): 曲线调整

用OpenCV实现Photoshop算法(四): 色阶调整

用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 <cstdio>
#include <iostream>
#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<Point> 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 ), 进行调整后







猜你喜欢

转载自blog.csdn.net/c80486/article/details/52506174