Curved Grayscale Transformation of Color Image



Preface

I learned a lot of new things through the homework procedures of the digital media experiment course. I will talk about the questions first, and then talk about it in detail. Title requirements: Refer to the "Curve Adjustment" function in PhotoShop, and use the knowledge you have learned to realize the curve grayscale transformation of color images.

 

  

  Of course, what I wrote is not as powerful as PS's functions. I only did a simple gamma transformation. Let's put the renderings of the program first.

 

  

Program analysis

Processing flow

First of all, OpenCV is used for image processing, and C# is used for graphical interface display. Why do programs use C# instead of C++ to write a graphical interface? MFC or Qt is definitely more convenient to write, but because I am currently learning WPF, I just use it to write these small programs to practice my skills. This program mainly consists of two parts (graphical interface done by C#, image processing done by C++), first set the gamma value in WPF, then pass the parameters to the C++ program, complete the image processing, and finally retrieve the C# program The processed image is displayed.

 

  

Difficulties

1. Curve chart in the upper right corner of the program 2. The "communication" between C# and C++ programs

solves the above two points, and the rest of the program is very simple. The following mainly explains these two problems.

Curve chart

Flowchart

 

  

Tips

For WPF programs, it is not difficult to achieve this function. 1. What controls are used? The Canvas+Thumb control is mainly used, and Thumb is not too cool to use... (Thumb control has a lot of information on the Internet, and I won't say much in this article. It mainly uses its three events DragStarted, DragDelta, DragCompleted).

2. How to draw a curve? A line is made of points, two points can form a straight line, and a curve is just a little more points (the more the smoother), and then the points are connected to form a curve. So through the formula of gamma conversion (Y=C*X^γ, C is a constant, set to 1), we can get many points on the curve, and then connect them to form a curve. It should be noted that the number of points to be taken is too many, which will inevitably affect the efficiency of the program. If it is too small, the curve will not be smooth enough, so just find a suitable number by yourself.

3. How to prevent the target point from going out of bounds? There are two methods: 1. Determine the coordinates of the Thumb control (relative to Canvas) 2. Determine the coordinate value of the mouse (relative to Canvas). I used the second one. The advantage is that it is relatively simple to implement. The disadvantage is that the mouse can only move the target point in the chart. After the chart is removed, the point cannot continue to move on the edge of the chart with the mouse. But it doesn't matter much, just a little bit of interactivity.

4. How does the slider control the display of the original image and the rendering image? This is very simple, by the way. In fact, it is two overlapping Image elements. The Image element that displays the rendering can control the transparency by the slider. The most convenient way is to use element binding to bind the Opacity property of Image to the value of Slider.

JAVA;">

Opacity="{Binding ElementName=TransparentSlider, Path=Value, Mode=OneWay}"

The "communication" between C# and C++ programs

cannot be called communication in the strict sense, it is mainly a way of calling programs Relationships, one-way information transfer. The process is that the C# program passes the three parameters of the image path to be processed, the gamm value, and the processing result image path to the C++ program. After the processing is completed, the C# program fetches the image.

So how do you pass these parameters to a C++ program? This involves process communication related content (pipe communication, shared memory, Socket, etc.), and I don't use such complicated technology, there is a very simple way, that is to use command line parameters! Often seen in C++ programs int main(int argc, char *argv[]) where int argc represents the number of parameters, and char *argv[] represents the parameters. Then use the Process class in C# to call the application and pass parameters to it. Take a look at the code in this part of C#:

JAVA;">

private void TransformImage(double gamm, string imagePath)

{

    //parameter 1 input path 2 gamma value 3 output path

    string argu_srcPath = imagePath;

    string argu_gamm = gamm.ToString( );

    string argu_resPath = resImageFilePath;


    Process process = new Process();

    //C++ program path

    process.StartInfo.FileName = currFilePath + "\\Project1.exe";

    process.StartInfo.Arguments = argu_srcPath + " " + argu_gamm + " " + argu_resPath;

    process.StartInfo.UseShellExecute = false;

    process.StartInfo.CreateNoWindow = true;

    process.Start();

    //Wait for the end of the program execution, and then continue to execute the code

    process.WaitForExit();

    process.Close();

}

And in the C++ code You only need to sequentially take the values ​​in the argv array to get the corresponding parameters.

Written at the end After

writing WinForm, it is still very cool to use WPF, especially the layout is so convenient to use. At present, this program still has shortcomings. For example, it only does JPG image processing; it only does gamma curve transformation, and it does not support multi-point adjustment (fitting function) like ps. How much more effort is needed! The project code is packaged and uploaded later.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326390738&siteId=291194637