曲线调整是Photoshop的最常用的重要功能之一。对于一个RGB图像, 可以对R, G, B 通道进行独立的曲线调整,即,对三个通道分别使用三条曲线(Curve)。还可以再增加一条曲线对 三个通道进行整体调整。 因此,对一个图像,可以用四条曲线调整。最终的结果,是四条曲线调整后合并产生的结果。

图中,横轴是输入,比左到右分别表示0到255. 纵轴是输出,从下到上分别表示0到255.
具体代码分三个实现:
头文件 Curves.h
/*
* Adjust Curves
*/
#ifndef OPENCV2_PS_CURVES_HPP_
#define OPENCV2_PS_CURVES_HPP_
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
namespace cv {
/**
* Class of Curve for one channel
*/
class Curve {
protected:
Scalar color;
Scalar back_color;
int tolerance; //
bool is_mouse_down;
vector<Point> points; //control points
vector<Point>::iterator current; //pointer to current point
vector<Point>::iterator find(int x);
vector<Point>::iterator find(int x, int y);
vector<Point>::iterator add(int x, int y);
public:
Curve();
virtual ~Curve();
int calcCurve(double* z); //
void draw(Mat& mat); //
void mouseDown(int x, int y);
bool mouseMove(int x, int y);
void mouseUp(int x, int y);
void clearPoints();
int addPoint(const Point& p);
int deletePoint(const Point& p);
int movePoint(const Point& p, int x, int y);
};
/**
* Class of Curves for all channels
*/
class Curves {
protected:
void createColorTables(uchar colorTables[][256]);
public:
Curves();
virtual ~Curves();
Curve RGBChannel; //RGB
Curve RedChannel; //Red
Curve GreenChannel; //Green
Curve BlueChannel; //Blue
Curve* CurrentChannel;
void draw(Mat& mat);
void mouseDown(int x, int y);
bool mouseMove(int x, int y);
void mouseUp(int x, int y);
int adjust(InputArray src, OutputArray dst, InputArray mask = noArray());
};
#endif/* OPENCV2_PS_CURVES_HPP_ */
void dot_line(Mat& mat, Point& p1, Point& p2, Scalar& color, int step = 8);
} /* namespace cv */
Curves.cpp
/*
* Adjust Curves
*
*/
#include "Curves.hpp"
#ifdef HAVE_OPENMP
#include <omp.h>
#endif
#define SWAP(a, b, t) do { t = a; a = b; b = t; } while(0)
#define CLIP_RANGE(value, min, max) ( (value) > (max) ? (max) : (((value) < (min)) ? (min) : (value)) )
#define COLOR_RANGE(value) CLIP_RANGE((value), 0, 255)
#include <iostream>
#define DEBUG_PRINT(a) cout << (a) << endl
#define PRINT_VAR(var) cout << #var << " = " << (var) << endl
namespace cv {
/**
* spline function
*
* @param x [in] array of x-coordinate of control points
* @param y [in] array of y-coordinate of control points
* @param n [in] count of control points
* @param t [in] array of x-coordinate of output points
* @param m [in] count of output points
* @param z [out] array of y-coordinate of output points
*/
static double spline(double* x, double* y, int n, double* t, int m, double* z)
{
double* dy = (double*)malloc(n * sizeof(int));
memset(dy, 0, sizeof(double) * n);
dy[0] = -0.5;
//double* ddy = new double[n];
double* ddy = (double*)malloc(n * sizeof(int));
memset(ddy, 0, sizeof(double) * n);
double h1;
double* s = (double*)malloc(n * sizeof(int));
double h0 = x[1] - x[0];
s[0] = 3.0 * (y[1] - y[0]) / (2.0 * h0) - ddy[0] * h0 / 4.0;
for (int j = 1; j <= n - 2; ++j)
{
h1 = x[j + 1] - x[j];
double alpha = h0 / (h0 + h1);
double beta = (1.0 - alpha) * (y[j] - y[j - 1]) / h0;
beta = 3.0 * (beta + alpha * (y[j + 1] - y[j]) / h1);
dy[j] = -alpha / (2.0 + (1.0 - alpha) * dy[j - 1]);
s[j] = (beta - (1.0 - alpha) * s[j - 1]);
s[j] = s[j] / (2.0 + (1.0 - alpha) * dy[j - 1]);
h0 = h1;
}
dy[n - 1] = (3.0 * (y[n - 1] - y[n - 2]) / h1 + ddy[n - 1] * h1 / 2.0 - s[n - 2]) / (2.0 + dy[n - 2]);
for (int j = n - 2; j >= 0; --j)
{
dy[j] = dy[j] * dy[j + 1] + s[j];
}
for (int j = 0; j <= n - 2; ++j)
{
s[j] = x[j + 1] - x[j];
}
for (int j = 0; j <= n - 2; ++j)
{
h1 = s[j] * s[j];
ddy[j

最低0.47元/天 解锁文章
677

被折叠的 条评论
为什么被折叠?



