http://blog.csdn.net/c80486/article/details/52499919
Series Articles:
Using OpenCV to realize Photoshop algorithm (a): Image rotation
Using OpenCV to realize Photoshop algorithm (ii): Image clipping
Using OPENCV to implement Photoshop algorithm (c): Curve adjustment
Using OpenCV to realize Photoshop algorithm (four): Color scale adjustment
Implementation of Photoshop algorithm with OpenCV (v): Brightness contrast adjustment
Implement Photoshop algorithm with OpenCV (vi): Black and white image
Implementation of the Photoshop algorithm with OpenCV (vii): adjust hue saturation
Implementing the Photoshop algorithm with OpenCV (eight): Optional color
Using OPENCV to implement Photoshop algorithm (ix): High Contrast retention
Three, curve adjustment (Curves adjustment)
Curve adjustment is one of the most common and important features of Photoshop.
The online material on the principle of curve technology is incomplete. After one months of exploration and experimentation, I used OPENCV to achieve the curve function, basically to uncover the "puzzle of the curve."
(i) The principle of the curve
For an RGB image, the R, G, and B channels can be adjusted independently, i.e. three curves (Curve) are used for three channels respectively. You can also add a curve to the overall adjustment of three channels. Therefore, for an image, you can adjust it with four curves. The final result is the result of the four-curve-adjusted merge.
Let's first analyze the principle of a single-channel curve, such as: Define a curve for the red channel as follows:
In the figure, the horizontal axis is the input, which represents 0 to 255, respectively, from left to right. The vertical axis is the output, which represents 0 to 255, respectively, from bottom to top.
The curve is defined by three points and the coordinates are: point 1 (0,0), point 2 (127,154), point 3 (255,255)
Point 1 and point 3 are generated by default, and point 2 is our new addition. Draw a curve (Spline) in these three points.
Implementation of the adjustment: when the input (red channel value) is X1, the output value (the new red channel value) is set to the value of the curve corresponding to Y1.
Code implementation: To scan all the pixels of the image, take the red value X1, for the corresponding Y1. The other two channel values (green-blue) are unchanged.
For example: Pixel rgb= (127, 230, 220), where the red value is X1 = 127, the value on the corresponding curve is Y1 = 154, then the rgb= of the pixel points after the curve of the channel is adjusted (154, 230, 220)
If the curve is only a 45-degree slash from the lower-left corner to the upper-right corner, the X1 is always equal to Y1, and the picture is unchanged after the curve is adjusted.
The three independent channels of red, green and blue are adjusted in the same way as the above algorithm. Each channel adjustment is non-relevant.
We then analyze the principle of overall tuning of the RGB channels.
For example: Pixel rgb= (127, 230, 220), the RGB channel for the overall adjustment, according to the curve at the same time R, G, b three values are adjusted.
R = 127 as input value, calculate the corresponding output value on the curve R1
G = 230 as the input value, calculate the corresponding output value on the curve G1
B = 220 as the input value, calculate the corresponding output value on the curve B1
Then RGB = (R1, G1, B1) of the new pixel point
With a few curves at the same time, the red, green, blue three independent channels are adjusted, and finally the total RGB channel adjustment.
Since the curve adjustment is only a numeric substitution, a conversion table can be used for fast operation, so the curve adjustment is fast.
(ii) Generation of curves
The curve used by Photoshop is a spline curve. This curve is very expressive, characterized by the need to define only a few control points, you can define a smooth curve, and the curve through all control points at the same time. When generating a curve, only a few control points need to be given, and the curve generation function can be called.
Spline specific mathematical principles I will not talk about, generate function can see the following source code Curves.cpp in the spline () function
(iii) OPENCV realization of curve adjustment
I wrote two C + + classes with OpenCV: The curves class realizes the definition, drawing and adjustment of multi-channel curves. The curve class is a curve definition class for a channel.
Source A total of two files: curves.hpp, Curves.cpp, source code and use the sample can be downloaded here: Curve algorithm source code
The source code has a certain length, not specifically explained, please see the note. A few additional notes:
1, the Curves class defines four curve objects (four channels), namely Redchannel, Greenchannel, Bluechannel, and Rgbchannel.
2, the Curves class supports the use of the mouse to generate curves, using the method see routines.
2, Curves.cpp in the spline () function is to generate a curve value, that is, input a string of control points, through the interpolation operation, generate a series of output values.
3, in addition to using the mouse to generate curves, you can also use the program code directly generated curves:
Use the Clearpoints () method of the Curve class to clear all control points, and then call the Addpoint () method to add control points one by one.
(d) Routine
Write a routine that uses the curves class to achieve a curve adjustment.
The program defines two windows, one is the picture window, and the other is the Curve window.
[CPP]View PlainCopy
- /*
- * Test_curves.cpp
- *
- * Created on:2016 Year September 11
- * Author:administrator
- */
- #include <cstdio>
- #include <iostream>
- #include "opencv2/core.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/highgui.hpp"
- #include "curves.hpp"
- Using namespace std;
- Using namespace CV;
- static string window_name = "Photo";
- static Mat src;
- static string Curves_window = "Adjust curves";
- Static Mat Curves_mat;
- static int channel = 0;
- Curves Curves;
- static void invalidate ()
- {
- Curves.draw (Curves_mat);
- Imshow (Curves_window, Curves_mat);
- Mat DST;
- Curves.adjust (SRC, DST);
- Imshow (Window_name, DST);
- int y, x;
- Uchar *p;
- y = 150; x = 50;
- p = dst.ptr<uchar> (y) + x * 3;
- cout << "(" << Int (p[2]) << "," << Int (p[1]) << "," << Int (p [0]) << ")";
- y = 150; x = 220;
- p = dst.ptr<uchar> (y) + x * 3;
- cout << "(" << Int (p[2]) << "," << Int (p[1]) << "," << Int (p [0]) << ")";
- y = 150; x = 400;
- p = dst.ptr<uchar> (y) + x * 3;
- cout << "(" << Int (p[2]) << "," << Int (p[1]) << "," << Int (p [0] << ")" << Endl;
- }
- static void Callbackadjustchannel (int, void *)
- {
- switch (channel) {
- Case 3:
- Curves. Currentchannel = &curves. Bluechannel;
- Break ;
- Case 2:
- Curves. Currentchannel = &curves. Greenchannel;
- Break ;
- Case 1:
- Curves. Currentchannel = &curves. Redchannel;
- Break ;
- Default:
- Curves. Currentchannel = &curves. Rgbchannel;
- Break ;
- }
- Invalidate ();
- }
- static void callbackmouseevent (int mouseEvent, int x, int y, int flags, void* param)
- {
- switch (mouseEvent) {
- Case Cv_event_lbuttondown:
- Curves.mousedown (x, y);
- Invalidate ();
- Break ;
- Case Cv_event_mousemove:
- if (curves.mousemove (x, y))
- Invalidate ();
- Break ;
- Case Cv_event_lbuttonup:
- Curves.mouseup (x, y);
- 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);
- //create Mat for curves
- Curves_mat = Mat::ones (CV_8UC3);
- //create window for curves
- Namedwindow (Curves_window);
- Setmousecallback (Curves_window, callbackmouseevent, NULL);
- Createtrackbar ("Channel", Curves_window, &channel, 3, Callbackadjustchannel);
- Example: Defining a curve in Redchannel with program code
- Curves. Redchannel.clearpoints ();
- Curves. Redchannel.addpoint (Point (10, 10));
- Curves. Redchannel.addpoint (Point (240, 240));
- Curves. Redchannel.addpoint (Point (127, 127));
- Invalidate ();
- Waitkey ();
- return 0;
- }
The results are as follows:
Original:
Curve adjustment of red channel (channels 1)
Then, for the RGB channel (channel 0) to a classic s-shaped curve adjustment
Oh, a little taste.
Series Articles:
Using OpenCV to realize Photoshop algorithm (a): Image rotation
Using OpenCV to realize Photoshop algorithm (ii): Image clipping
Using OPENCV to implement Photoshop algorithm (c): Curve adjustment
Using OpenCV to realize Photoshop algorithm (four): Color scale adjustment
Implementation of Photoshop algorithm with OpenCV (v): Brightness contrast adjustment
Using OPENCV to implement Photoshop algorithm (c): Curve adjustment