https://www.cnblogs.com/sevenyuan/p/7874344.html
Sobel operator is a discrete differential operator (discrete differentiation operator). It combines differential Gaussian smoothing derivative and for calculating image intensity gradient of the approximate function.
Edge image, with pixel values of significant changes occurred. This change represents a method of using the derivative. Drastic change gradient values indicate a significant change in image content. More vivid image to explain, suppose we have a Zhang Yiwei graphics. 2. FIG lower gradation value "jump" indicates the presence of an edge, and Figure 3 a first-order differential derivation we can more clearly see the edge of "jump" exists.
1 #include <iostream> 2 #include <opencv2/core.hpp> 3 #include <opencv2/highgui.hpp> 4 #include <opencv2/imgproc.hpp> 5 6 //阶乘 7 int factorial(int n){ 8 int fac = 1; 9 //0的阶乘 10 if (n == 0) 11 return fac; 12 for (int i = 1; i <= n; ++i){ 13 fac *= i; 14 } 15 return fac; 16 } 17 18 //获得Sobel平滑算子 19 cv::Mat getSobelSmoooth(int wsize){ 20 int n = wsize - 1; 21 cv::Mat SobelSmooothoper=cv::Mat::zeros(cv::Size(wsize,1),CV_32FC1); 22 for (int k = 0; k <= n; k++){ 23 float *pt = SobelSmooothoper.ptr<float>(0); 24 pt[k] = factorial(n) / (factorial(k)*factorial(n - k)); 25 } 26 return SobelSmooothoper; 27 } 28 29 //获得Sobel差分算子 30 cv::Mat getSobeldiff(int wsize){ 31 cv::Mat Sobeldiffoper = cv::Mat::zeros(cv::Size(wsize, 1), CV_32FC1); 32 cv::Mat SobelSmoooth = getSobelSmoooth(wsize - 1); 33 for (int k = 0; k < wsize; k++){ 34 if (k == 0) 35 Sobeldiffoper.at<float>(0, k) = 1; 36 else if (k == wsize - 1) 37 Sobeldiffoper.at<float>(0, k) = -1; 38 else 39 Sobeldiffoper.at<float>(0, k) = SobelSmoooth.at<float>(0, k) - SobelSmoooth.at<float>(0, k - 1); 40 } 41 return Sobeldiffoper; 42 } 43 44 // Convolutions 45 void conv2D (CV :: Mat & the src, CV :: Mat & DST, CV :: Mat Kernel, int ddepth, CV = CV :: :: Point Anchor Point (- . 1 , - . 1 ), int = Delta 0 , int borderType = CV :: BORDER_DEFAULT) { 46 is CV :: Mat kernelFlip; 47 CV :: Flip (Kernel, kernelFlip, - . 1 ); 48 CV :: filter2D (the src, DST, ddepth, kernelFlip, Anchor, Delta, borderType); 49 } 50 51 is 52 is // separable vertical convolution to convolution ---, the horizontal convolution 53 is voidsepConv2D_Y_X (CV :: Mat & the src, Mat & DST CV ::, :: Mat kernel_Y CV, CV :: Mat kernel_X, int ddepth, CV = CV :: :: Point Anchor Point (- . 1 , - . 1 ), int Delta = 0 , int borderType = CV :: BORDER_DEFAULT) { 54 is CV :: Mat dst_kernel_Y; 55 conv2D (the src, dst_kernel_Y, kernel_Y, ddepth, Anchor, Delta, borderType); // vertical convolution 56 is conv2D (dst_kernel_Y, DST, kernel_X , ddepth, Anchor, Delta, borderType); // horizontal convolution 57 } 58 59 // separable convolution convolution --- first horizontal direction, the vertical direction after convolution 60 voidsepConv2D_X_Y (CV :: Mat & the src, Mat & DST CV ::, :: Mat kernel_X CV, CV :: Mat kernel_Y, int ddepth, CV = CV :: :: Point Anchor Point (- . 1 , - . 1 ), int Delta = 0 , int borderType = CV :: BORDER_DEFAULT) { 61 is CV :: Mat dst_kernel_X; 62 is conv2D (the src, dst_kernel_X, kernel_X, ddepth, Anchor, Delta, borderType); // horizontal convolution 63 is conv2D (dst_kernel_X, DST, kernel_Y , ddepth, Anchor, Delta, borderType); // vertical convolution 64 } 65 66 67 // the Sobel edge detection operator 68 @dst_X vertical direction 69 // dst_Y horizontal direction 70 void the Sobel (CV :: Mat & the src, Mat & dst_X CV ::, :: Mat & dst_Y CV, CV :: Mat & DST, int the wsize, int ddepth, CV = CV :: Anchor Point Point :: (- . 1 , - . 1 ), int Delta = 0 , int borderType = CV :: BORDER_DEFAULT) { 71 is 72 CV :: = getSobelSmoooth Mat SobelSmooothoper (the wsize); // smoothing coefficient 73 is CV :: = getSobeldiff Mat Sobeldiffoper (the wsize); // differential coefficient 74 75 @ detachably to the vertical direction smoothing convolution ---, the difference in the horizontal direction - vertical edge to give 76 sepConv2D_Y_X (the src, dst_X, SobelSmooothoper.t (), Sobeldiffoper, ddepth); 77 78 // separable convolution --- first horizontal direction smoothing, the difference in the vertical direction - horizontal edges to obtain 79 sepConv2D_X_Y (the src, dst_Y, SobelSmooothoper , Sobeldiffoper.t (), ddepth); 80 81 // edge strength (approximately) 82 DST = ABS (dst_X) + ABS (dst_Y); 83 CV :: convertScaleAbs (DST, DST); // absolute value and transfers FIG 8 is an unsigned 84 CV :: convertScaleAbs (dst_X, dst_X); // absolute value and converted to unsigned 8-bit in FIG. 85 CV :: convertScaleAbs (dst_Y, dst_Y); 86 // CV :: POW (dst_X , 2.0, dst_X); 87 // CV :: POW (dst_Y, 2.0, dst_Y); 88 //cv::sqrt(dst_X + dst_Y, dst); 89 //dst.convertTo(dst, CV_8UC1); 90 } 91 92 93 int main(){ 94 cv::Mat src = cv::imread("E://lena.jpg"); 95 if (src.empty()){ 96 return -1; 97 } 98 if (src.channels() > 1) cv::cvtColor(src, src, CV_RGB2GRAY); 99 int wsize = 3; 100 cv::Mat Sobeldiffoper, SobelSmooothoper; 101 SobelSmooothoper = getSobelSmoooth (the wsize); 102 Sobeldiffoper = getSobeldiff (the wsize); 103 104 // NOTE: To use CV_32F, because convolution may be negative, if the unsigned 8 bits, will result in those places 0 105 CV Mat DST ::, dst_X, dst_Y; 106 the Sobel (the src, dst_X, dst_Y, DST, the wsize, CV_32FC1); 107 CV :: namedWindow ( " the src " , CV_WINDOW_NORMAL); 108 imshow ( " the src " , the src); 109 CV namedWindow :: ( " horizontal edge " , CV_WINDOW_NORMAL); 110 imshow ( " horizontal edges" , Dst_Y); 111 CV :: namedWindow ( " vertical edge " , CV_WINDOW_NORMAL); 112 imshow ( " vertical edge " , dst_X); 113 // CV :: namedWindow (" edge intensity ", CV_WINDOW_NORMAL); 114 imshow ( " edge strength " , DST); 115 CV :: namedWindow ( " edge intensity inversion - pencil sketches " , CV_WINDOW_NORMAL); 1 16 imshow ( " edge intensity inversion - pencil sketches " , 255 - DST); 117 1 18 STD :: COUT << "SobelSmooothoper: "<< SobelSmooothoper << std::endl; 119 std::cout << "Sobeldiffoper: " << Sobeldiffoper << std::endl; 120 cv::waitKey(0); 121 return 0; 122 }