There are three basic steps to perform edge detection:
1. Smooth the image for noise reduction. Derivatives are sensitive to noise. Difficult to detect positive and negative components of images)
2. Detection of edge points. (Extracting potential candidates for edge points)
3. Edge positioning. (Select really marginal members from the candidates)
Basic operator: gradient operator (representing the edge intensity and direction of a point, also known as edge detector)
Relatively simple edge detection operator template:
Sobel template can suppress noise well.
The absolute value is often used to approximate the gradient amplitude, keeping the relative change of gray level, at the cost of causing the filter to be no longer isotropic.
Sobel calculation process
Opencv library function call method:
void Sobel (
InputArray src,
OutputArray dst,
int ddepth,
Int dx, the difference order in the x direction
Int dy, the difference order in the y direction
Int ksize=3, the size of the core is odd
Double scale=1, the scaling factor for computing the derivative
Double delta=0, an optional value before saving the result to the target image
int borderType=BORDER_DEFAULT ) ;
int main(a)
{
// Read image Read image
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); // The font is green
// Load the original image
Mat srcImage = imread("D:\\opencv_picture_test\\ morphologic operation \\coin_inv.png".0); // Read the grayscale image
// Check whether the image is loaded successfully
if (srcImage.empty())
{
cout << "Image load failed!" << endl;
return - 1;
}
else
cout << "Image load successful!" << endl << endl;
Mat gradx, grady;
Mat abs_gradx, abs_grady;
Mat dstImage;
// Find the x gradient
Sobel(srcImage,gradx,CV_16S,1.0.3.1.1,BORDER_DEFAULT);// 1 difference in the x direction and 0 difference in the y direction
convertScaleAbs(gradx, abs_gradx); / / the absolute value
// Find the y gradient
Sobel(srcImage, grady, CV_16S, 0.1.3.1.1, BORDER_DEFAULT);// 1 difference in the x direction and 0 difference in the y direction
convertScaleAbs(grady, abs_grady); / / the absolute value
addWeighted(abs_gradx,0.5, abs_grady,0.5.0,dstImage);
imshow("srcImage", srcImage);
imshow("X", abs_gradx);
imshow("Y direction", abs_grady);
imshow("Whole", dstImage);
waitKey(0);
return 0;
}
Copy the code
After ImageWatch magnification, it is found that the extracted edge is relatively thick.
There are two ways to reduce precision detail:
1. Smooth the image (for example, get the main edge by means filtering)
2. Perform threshold processing on gradient images (gradient amplitude greater than or equal to the threshold is black and white, less than the threshold is black), but this method is easy to break lines.
Both smoothing and thresholding are used when highlighting major edges and maintaining as much continuity as possible.
Roberts, Prewitt and Sobel operators all filter with one or more templates without taking protective measures against image characteristics and noise content.
Then introduce an optimal edge detection method: Canny operator
Low error rate: identify as many actual edges as possible, while minimizing false positives generated by noise. ● High positioning: the marked edge should be as close as possible to the actual edge in the image. ● Minimum response: Edges in the image can only be identified once, and possible image noise should not be identified as edges.
Canny operator calculation process
Opencv library function call method:
Void Canny (InputArray image, OutputArray edges, Double Threshold1, double Threshold2); the lower threshold is used for edge connection, and the larger threshold is used to control the initial end of the strong edge. Int apertureSize=3, sobel core size bool L2gradient=false)
int main(a)
{
// Read image Read image
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); // The font is green
// Load the original image
Mat srcImage = imread("D:\\opencv_picture_test\\ morphologic operation \\coin_inv.png".0); // Read the grayscale image
// Check whether the image is loaded successfully
if (srcImage.empty())
{
cout << "Image load failed!" << endl;
return - 1;
}
else
cout << "Image load successful!" << endl << endl;
Mat dstImage;
Canny(srcImage,dstImage,100.33.3.false);
imshow("srcImage", srcImage);
imshow("Whole", dstImage);
waitKey(0);
return 0;
}
Copy the code
Effect:
After ImageWatch magnifies, it can be found that the edge has only one lattice
In general, canny operator does have advantages.
Laplace process
3*3 aperture template:
Opencv library function call:
int main(a)
{
// Read image Read image
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN); // The font is green
// Load the original image
Mat srcImage = imread("D:\\opencv_picture_test\\ morphologic operation \\coin_inv.png".0); // Read the grayscale image
// Check whether the image is loaded successfully
if (srcImage.empty())
{
cout << "Image load failed!" << endl;
return - 1;
}
else
cout << "Image load successful!" << endl << endl;
Mat dstImage,abs_dst;
GaussianBlur(srcImage,srcImage,Size(3.3),0); // Gaussian blur
Laplacian(srcImage,dstImage,CV_16S,3.1.0);
convertScaleAbs(dstImage, abs_dst);
imshow("srcImage", srcImage);
imshow("Whole", dstImage);
waitKey(0);
return 0;
}
Copy the code