https://blog.csdn.net/c80486/article/details/51867128
For a photo, the general processing steps of PS include:
1. Rotate the picture and correct the position.
2. Cut, resize and reconstruct.
3. Adjust the color order and curve to make the pictures exposed correctly and contrast moderately.
4. Adjust contrast and saturation
5. Seals remove unwanted items and liquefy to adjust body lines.
6. For portrait pictures, skin and whitening
7. Use color balance and optional color to adjust the tone to form the tone of the photo.
8. Add some light efficiency
9, sharpen
In the future, a series of blogs will use OpenCV to realize the algorithm and function of Photoshop one by one, and try to surpass Photoshop a little by using computer vision artificial intelligence.
This series of blog posts is based on OpenCV and the programming language is C++. Because of the cross-platform nature of OpenCV, the code can be used in Windows, Linux, Android,IOS as an interface.
I. Image Rotation
In OpenCV, the warpAffine() affine transformation function is used to realize rotation.
For example, write a rotation function imageRotate1() as follows:
- #include <opencv2/core.hpp>
- #include <opencv2/imgproc.hpp>
- //src is the original image, dst is the new image, and angle is the rotation angle (positive value is clockwise rotation, negative value is counterclockwise rotation)
- int imageRotate1(InputArray src, OutputArray dst, double angle)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(width, height));
- return 0;
- }
In the function imageRotate1(), the new image follows the original image size. After rotation, the corner of the image is cut off.
This is obviously incorrect, and the image size needs to be adjusted.
Adjustment 1: Enlarge the picture and include the original picture. The calculation sketch is as follows:
The new image size is: out_width = width * cos (a) + height * sin (a); out_height = height*cos(a)+width*sin(a)).
Modify the original function to imageRotate2():
- //Image rotation: src is the original image, dst is the new image, and angle is the rotation angle
- int imageRotate2(InputArray src, OutputArray dst, double angle)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //Calculate new image size
- double angle1 = angle * CV_PI / 180. ;
- double a = sin(angle1) * scale;
- double b = cos(angle1) * scale;
- double out_width = height * fabs(a) + width * fabs(b);
- double out_height = width * fabs(a) + height * fabs(b);
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(out_width, out_height));
- return 0;
- }
Result of image rotation - 17 degrees
Or not, the new image becomes larger, but the center of the image is not right. It needs to add translation in the rotation matrix, complete rotation and translation simultaneously in a transformation, and move the center of the new image to the correct position.
Modify the function again to: imageRotate3()
- //Image rotation: src is the original image, dst is the new image, and angle is the rotation angle
- int imageRotate3(InputArray src, OutputArray dst, double angle)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //Calculate new image size
- double angle1 = angle * CV_PI / 180. ;
- double a = sin(angle1) * scale;
- double b = cos(angle1) * scale;
- double out_width = height * fabs(a) + width * fabs(b);
- double out_height = width * fabs(a) + height * fabs(b);
- //Adding translations to the rotation transformation matrix
- trans_mat.at<double>(0, 2) += cvRound( (out_width - width) / 2 );
- trans_mat.at<double>(1, 2) += cvRound( (out_height - height) / 2);
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(out_width, out_height));
- return 0;
- }
This time correctly, the new image becomes larger, and the center of the image moves to the new center, the original image can be displayed.
In actual photo rotation, we often use another way of adjusting the cut form: after image rotation, reduce the image, so that no black edges appear in every corner of the picture. The following red box is the new image size, as follows:
In this way, the calculation of the size of the new image is a little complicated, and there is no example found on the Internet, so it can only be calculated by itself.
1. As above, the size of the outer border after rotation is as follows: out_width= (width*cos(a)+height*sin(a); (out_height=height*cos(a)+width*sin(a).)
2. Draw some auxiliary lines as follows: (Note the pink triangle in the right-hand picture)
The longest side length len = width*cos(a)
Angle a is the rotation angle.
Since the size of the outer border is known, the angle b can be calculated.
Solution Y: Y = len / 1 / Tan (a) + 1 / Tan (b)
X = Y * 1 / tan( b )
Finally, the length and width of the red box are: new_width = out_width - 2 * X; new_height = out_height - 2 * Y.
Modify the function again to: imageRotate4()
Added a parameter: isClip, when isClip is true, take the cut mode of reducing the picture, otherwise take the way of enlarging the picture.
- //Image rotation: src is the original image, dst is the new image, angle is the rotation angle, isClip means to reduce the image.
- int imageRotate4(InputArray src, OutputArray dst, double angle, bool isClip)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //Calculate new image size
- double angle1 = angle * CV_PI / 180. ;
- double a = sin(angle1) * scale;
- double b = cos(angle1) * scale;
- double out_width = height * fabs(a) + width * fabs(b); //Outer border length
- double out_height = width * fabs(a) + height * fabs(b);//Outer frame height
- int new_width, new_height;
- if ( ! isClip ) {
- new_width = cvRound(out_width);
- new_height = cvRound(out_height);
- } else {
- //calculate width and height of clip rect
- double angle2 = fabs(atan(height * 1.0 / width)); //Angle b
- double len = width * fabs(b);
- double Y = len / ( 1 / fabs(tan(angle1)) + 1 / fabs(tan(angle2)) );
- double X = Y * 1 / fabs(tan(angle2));
- new_width = cvRound(out_width - X * 2);
- new_height= cvRound(out_height - Y * 2);
- }
- //Adding translations to the rotation transformation matrix
- trans_mat.at<double>(0, 2) += cvRound( (new_width - width) / 2 );
- trans_mat.at<double>(1, 2) += cvRound( (new_height - height) / 2);
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(new_width, new_height));
- return 0;
- }
Following is the result of isClip's true rotation angle of 10. It can be seen that the image has been rotated and shrunk with no black edge.
Because of the lack of attention, people often take pictures skewed, usually not much, but the pictures are not good-looking.
Therefore, there is a problem: whether the image can be judged intelligently, and if it is skewed, the angle to be rotated can be calculated automatically. As a result, people take photos automatically.
PS: This function is not available in Photoshop, if it can be implemented, it is not a little bit more than Photoshop?
The solution is as follows:
1. The image usually has one or two long straight lines (usually this may be the horizon, buildings, etc.) and the tilt angle is small.
2. Using OpenCV image recognition ability, we can identify which lines are in the graph.
3. Analyse these lines. If the length is long enough and the position is relatively in the middle, choose the longest two lines and calculate the angle needed to set them right as the return value.
In fact, the same is true of the manual Photoshop operation: we find a baseline for the human eye in the picture, draw a line with the Measuring Tool, and then click on the menu "Image/Rotary Canvas/Arbitrary Angle", then Photoshop will calculate the angle that needs to be rotated.
We try to write a function: detectRotation(). It is used to automatically detect the rotation angle of the pendulum image.
- /**
- * Intelligent Detection of Image Tilt
- * Return value: Return 0 indicates no detection result, return non-zero indicates the angle of rotation of the pendulum image (-10 to 10 degrees)
- */
- double detectRotation(InputArray src)
- {
- double max_angle = 6; //Maximum Rotating Angle
- Mat in = src.getMat();
- if( in.empty() ) return 0;
- Mat input;
- //Conversion to grayscale
- if ( in.type() == CV_8UC1 )
- input = in;
- else if ( in.type() == CV_8UC3 )
- cvtColor(in, input, CV_BGR2GRAY);
- else if ( in.type() == CV_8UC3 )
- cvtColor(in, input, CV_BGRA2GRAY);
- else
- return 0;
- Mat dst, cdst;
- //Perform Canny edge detection (detection result is dst, black-and-white image)
- double threshold1 = 90;
- Canny(src, dst, threshold1, threshold1 * 3, 3);
- //Converting Canny edge detection results into gray scale images (cdst)
- cvtColor(dst, cdst, CV_GRAY2BGR);
- //Perform Hough Line Transform to Detect Lines
- vector<Vec4i> lines; //vector for storing test results
- double minLineLength = std::min(dst.cols, dst.rows) * 0.25; //Minimum Line Length
- double maxLineGap = std::min(dst.cols, dst.rows) * 0.03 ; //Minimum line spacing
- int threshold = 90;
- HoughLinesP(dst, lines, 1, CV_PI / 180, threshold, minLineLength, maxLineGap );
- //Analysis of required variables
- int x1, y1, x2 , y2; //Two Endpoints of a Line
- int x, y; //The midpoint of a straight line
- double angle, rotate_angle; //The angle at which a straight line needs to be rotated.
- double line_length; //Straight line length
- double position_weighted; //Line position weight: Line weight by the center of the image is 1, the smaller the line weight by the edge is.
- double main_lens[2]; //An array for storing the longest two straight lines (the two lines are the main lines)
- double main_angles[2];//The angle of rotation required for the alignment of the longest two straight lines
- main_lens[0] = main_lens[1] = 0;
- main_angles[0] = main_angles[1] = 0;
- //Analyse each line one by one to determine which is the main line.
- for( size_t i = 0; i < lines.size(); i++ ) {
- //Get the coordinates of two endpoints of a straight line
- x1 = lines[i][0]; y1 = lines[i][1]; x2 = lines[i][2]; y2 = lines[i][3];
- x = (x1 + x2 ) / 2; y = (y1 + y2) / 2;
- //Calculate the angle of a straight line
- angle = (x1 == x2) ? 90 : ( atan ( (y1 - y2) * 1.0 / (x2 - x1) ) ) / CV_PI * 180;
- //Orthogonal alignment requires an angle of rotation. If the maximum angle of rotation is exceeded, the line is ignored.
- if ( fabs(angle - 0) <= max_angle ) {
- rotate_angle = angle - 0;
- } else if ( fabs(angle - 90) <= max_angle ) {
- rotate_angle = angle - 90;
- } else {
- continue;
- }
- //Calculate the length of the line
- line_length = sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
- //Calculate the position weight of straight line: The line weight is 1 in the center of the image, and the smaller the line weight is, the more the line weight is, the smaller the line weight is.
- position_weighted = 1;
- if ( x < dst.cols / 4 || x > dst.cols * 3 / 4 ) position_weighted *= 0.8;
- if ( x < dst.cols / 6 || x > dst.cols * 5 / 6 ) position_weighted *= 0.5;
- if ( x < dst.cols / 8 || x > dst.cols * 7 / 8 ) position_weighted *= 0.5;
- if ( y < dst.rows / 4 || y > dst.rows * 3 / 4 ) position_weighted *= 0.8;
- if ( y < dst.rows / 6 || y > dst.rows * 5 / 6 ) position_weighted *= 0.5;
- if ( y < dst.rows / 8 || y > dst.rows * 7 / 8 ) position_weighted *= 0.5;
- //If the line length * position weight < minimum length, the line is invalid
- line_length = line_length * position_weighted;
- if ( line_length < minLineLength ) continue;
- //If the length is the first two, the data is stored
- if ( line_length > main_lens[1] ) {
- if (line_length > main_lens[0]) {
- main_lens[1] = main_lens[0];
- main_lens[0] = line_length;
- main_angles[1] = main_angles[0];
- main_angles[0] = rotate_angle;
- //If SHOW_LINE is defined, the line is drawn.
- #ifdef SHOW_LINE
- line( cdst, Point(x1, y1), Point(x2, y2), Scalar(0,0,255), 3, CV_AA);
- #endif
- } else {
- main_lens[1] = line_length;
- main_angles[1] = rotate_angle;
- }
- }
- }
- //If SHOW_LINE is defined, cdst is displayed in source_window
- #ifdef SHOW_LINE
- imshow(source_window, cdst);
- #endif
- //Finally, the longest two straight lines are analyzed and the results are obtained.
- if ( main_lens[0] > 0 ) {
- //If the length of the longest line is similar to that of the second line, return the average of the angles at which they need to rotate.
- if (main_lens[1] > 0 && (main_lens[0] - main_lens[1] / main_lens[0] < 0.2 )) {
- return (main_angles[0] + main_angles[1] ) / 2;
- } else {
- return main_angles[0]; //Otherwise, returning to the longest line requires an angle of rotation.
- }
- } else {
- return 0;
- }
- }
The detection Rotation () function is used to automatically test the angle and display the main lines.
Well, it's a little interesting. Find out several main lines and get a rotation of - 5 degrees. Then you can put the picture right.
Of course, the detectRotation() function is not very intelligent, and its usability needs to be improved.
Finally, paste all the code and the main program in this article (a bit long, but easy to copy). Configure the OpenCV development environment, copy the code and debug it.
It should be noted in the code that the scroll bar of opencv can only display positive values. In this case, the rotation scroll bar, with a value of 100, indicates that the rotation angle is 0. If less than 100, the rotation angle is negative.
- #include <iostream>
- #include "opencv2/core.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/highgui.hpp"
- #include <cmath>
- using namespace std;
- using namespace cv;
- #define SHOW_LINE
- #define BASE 100
- static string source_window = "source";
- static string window_name = "image rotate";
- static Mat src;
- static int rotateDegree = 0 + BASE;
- static int clip = 0;
- //Image rotation: src is the original image, dst is the new image, and angle is the rotation angle (positive value is clockwise rotation, negative value is counterclockwise rotation)
- int imageRotate1(InputArray src, OutputArray dst, double angle)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(width, height));
- return 0;
- }
- //Image rotation: src is the original image, dst is the new image, and angle is the rotation angle
- int imageRotate2(InputArray src, OutputArray dst, double angle)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //Calculate new image size
- double angle1 = angle * CV_PI / 180. ;
- double a = sin(angle1) * scale;
- double b = cos(angle1) * scale;
- double out_width = height * fabs(a) + width * fabs(b);
- double out_height = width * fabs(a) + height * fabs(b);
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(out_width, out_height));
- return 0;
- }
- //Image rotation: src is the original image, dst is the new image, and angle is the rotation angle
- int imageRotate3(InputArray src, OutputArray dst, double angle)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //Calculate new image size
- double angle1 = angle * CV_PI / 180. ;
- double a = sin(angle1) * scale;
- double b = cos(angle1) * scale;
- double out_width = height * fabs(a) + width * fabs(b);
- double out_height = width * fabs(a) + height * fabs(b);
- //Adding translations to the rotation transformation matrix
- trans_mat.at<double>(0, 2) += cvRound( (out_width - width) / 2 );
- trans_mat.at<double>(1, 2) += cvRound( (out_height - height) / 2);
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(out_width, out_height));
- return 0;
- }
- //Image rotation: src is the original image, dst is the new image, angle is the rotation angle, isClip means to reduce the image.
- int imageRotate4(InputArray src, OutputArray dst, double angle, bool isClip)
- {
- Mat input = src.getMat();
- if( input.empty() ) {
- return -1;
- }
- //Get image size
- int width = input.cols;
- int height = input.rows;
- //Computing image centers
- Point2f center;
- center.x = width / 2.0;
- center.y = height / 2.0;
- //Obtaining Rotation Transform Matrix
- double scale = 1.0;
- Mat trans_mat = getRotationMatrix2D( center, -angle, scale );
- //Calculate new image size
- double angle1 = angle * CV_PI / 180. ;
- double a = sin(angle1) * scale;
- double b = cos(angle1) * scale;
- double out_width = height * fabs(a) + width * fabs(b); //Outer border length
- double out_height = width * fabs(a) + height * fabs(b);//Outer frame height
- int new_width, new_height;
- if ( ! isClip ) {
- new_width = cvRound(out_width);
- new_height = cvRound(out_height);
- } else {
- //calculate width and height of clip rect
- double angle2 = fabs(atan(height * 1.0 / width)); //Angle b
- double len = width * fabs(b);
- double Y = len / ( 1 / fabs(tan(angle1)) + 1 / fabs(tan(angle2)) );
- double X = Y * 1 / fabs(tan(angle2));
- new_width = cvRound(out_width - X * 2);
- new_height= cvRound(out_height - Y * 2);
- }
- //Adding translations to the rotation transformation matrix
- trans_mat.at<double>(0, 2) += cvRound( (new_width - width) / 2 );
- trans_mat.at<double>(1, 2) += cvRound( (new_height - height) / 2);
- //affine transformation
- warpAffine( input, dst, trans_mat, Size(new_width, new_height));
- return 0;
- }
- /**
- * Detection of image tilt
- * Return value: Return 0 indicates no detection result, return non-zero indicates the angle of rotation of the pendulum image (-10 to 10 degrees)
- */
- double detectRotation(InputArray src)
- {
- double max_angle = 6; //Maximum Rotating Angle
- Mat in = src.getMat();
- if( in.empty() ) return 0;
- Mat input;
- //Conversion to grayscale
- if ( in.type() == CV_8UC1 )
- input = in;
- else if ( in.type() == CV_8UC3 )
- cvtColor(in, input, CV_BGR2GRAY);
- else if ( in.type() == CV_8UC3 )
- cvtColor(in, input, CV_BGRA2GRAY);
- else
- return 0;
- Mat dst, cdst;
- //Perform Canny edge detection (detection result is dst, black-and-white image)
- double threshold1 = 90;
- Canny(src, dst, threshold1, threshold1 * 3, 3);
- //Converting Canny edge detection results into gray scale images (cdst)
- cvtColor(dst, cdst, CV_GRAY2BGR);
- //Perform Hough Line Transform to Detect Lines
- vector<Vec4i> lines; //vector for storing test results
- double minLineLength = std::min(dst.cols, dst.rows) * 0.25; //Minimum Line Length
- double maxLineGap = std::min(dst.cols, dst.rows) * 0.03 ; //Minimum line spacing
- int threshold = 90;
- HoughLinesP(dst, lines, 1, CV_PI / 180, threshold, minLineLength, maxLineGap );
- //Analysis of required variables
- int x1, y1, x2 , y2; //Two Endpoints of a Line
- int x, y; //The midpoint of a straight line
- double angle, rotate_angle; //The angle at which a straight line needs to be rotated.
- double line_length; //Straight line length
- double position_weighted; //Line position weight: Line weight by the center of the image is 1, the smaller the line weight by the edge is.
- double main_lens[2]; //An array for storing the longest two straight lines (the two lines are the main lines)
- double main_angles[2];//The angle of rotation required for the alignment of the longest two straight lines
- main_lens[0] = main_lens[1] = 0;
- main_angles[0] = main_angles[1] = 0;
- //Analyse each line one by one to determine which is the main line.
- for( size_t i = 0; i < lines.size(); i++ ) {
- //Get the coordinates of two endpoints of a straight line
- x1 = lines[i][0]; y1 = lines[i][1]; x2 = lines[i][2]; y2 = lines[i][3];
- x = (x1 + x2 ) / 2; y = (y1 + y2) / 2;
- //Calculate the angle of a straight line
- angle = (x1 == x2) ? 90 : ( atan ( (y1 - y2) * 1.0 / (x2 - x1) ) ) / CV_PI * 180;
- //Orthogonal alignment requires an angle of rotation. If the maximum angle of rotation is exceeded, the line is ignored.
- if ( fabs(angle - 0) <= max_angle ) {
- rotate_angle = angle - 0;
- } else if ( fabs(angle - 90) <= max_angle ) {
- rotate_angle = angle - 90;
- } else {
- continue;
- }
- //Calculate the length of the line
- line_length = sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
- //Calculate the position weight of straight line: The line weight is 1 in the center of the image, and the smaller the line weight is, the more the line weight is, the smaller the line weight is.
- position_weighted = 1;
- if ( x < dst.cols / 4 || x > dst.cols * 3 / 4 ) position_weighted *= 0.8;
- if ( x < dst.cols / 6 || x > dst.cols * 5 / 6 ) position_weighted *= 0.5;
- if ( x < dst.cols / 8 || x > dst.cols * 7 / 8 ) position_weighted *= 0.5;
- if ( y < dst.rows / 4 || y > dst.rows * 3 / 4 ) position_weighted *= 0.8;
- if ( y < dst.rows / 6 || y > dst.rows * 5 / 6 ) position_weighted *= 0.5;
- if ( y < dst.rows / 8 || y > dst.rows * 7 / 8 ) position_weighted *= 0.5;
- //If the line length * position weight < minimum length, the line is invalid
- line_length = line_length * position_weighted;
- if ( line_length < minLineLength ) continue;
- //If the length is the first two, the data is stored
- if ( line_length > main_lens[1] ) {
- if (line_length > main_lens[0]) {
- main_lens[1] = main_lens[0];
- main_lens[0] = line_length;
- main_angles[1] = main_angles[0];
- main_angles[0] = rotate_angle;
- //If SHOW_LINE is defined, the line is drawn.
- #ifdef SHOW_LINE
- line( cdst, Point(x1, y1), Point(x2, y2), Scalar(0,0,255), 3, CV_AA);
- #endif
- } else {
- main_lens[1] = line_length;
- main_angles[1] = rotate_angle;
- }
- }
- }
- //If SHOW_LINE is defined, cdst is displayed in source_window
- #ifdef SHOW_LINE
- imshow(source_window, cdst);
- #endif
- //Finally, the longest two straight lines are analyzed and the results are obtained.
- if ( main_lens[0] > 0 ) {
- //If the length of the longest line is similar to that of the second line, return the average of the angles at which they need to rotate.
- if (main_lens[1] > 0 && (main_lens[0] - main_lens[1] / main_lens[0] < 0.2 )) {
- return (main_angles[0] + main_angles[1] ) / 2;
- } else {
- return main_angles[0]; //Otherwise, returning to the longest line requires an angle of rotation.
- }
- } else {
- return 0;
- }
- }
- static void callbackAdjust(int , void *)
- {
- Mat dst;
- //imageRotate1(src, dst, rotateDegree - BASE);
- //imageRotate2(src, dst, rotateDegree - BASE);
- //imageRotate3(src, dst, rotateDegree - BASE);
- bool isClip = ( clip == 1 );
- imageRotate4(src, dst, rotateDegree - BASE, isClip );
- imshow(window_name, dst);
- }
- int main()
- {
- src = imread("building.jpg");
- if ( !src.data ) {
- cout << "error read image" << endl;
- return -1;
- }
- namedWindow(source_window);
- imshow(source_window, src);
- namedWindow(window_name);
- createTrackbar("rotate", window_name, &rotateDegree, BASE * 2, callbackAdjust);
- createTrackbar("clip", window_name, &clip, 1, callbackAdjust);
- //Automatic Detection of Rotation Angle
- double angle = detectRotation(src);
- if ( angle != 0 ) {
- rotateDegree = angle + BASE;
- setTrackbarPos("rotate", window_name, rotateDegree);
- }
- callbackAdjust(0, 0);
- waitKey();
- return 0;
- }