原理参考:
https://blog.csdn.net/tigerda/article/details/61192943
https://blog.csdn.net/jia20003/article/details/41173767
使用sobel算子实现:
edgedetector.h
#if !defined SOBELEDGES
#define SOBELEDGES
#define PI 3.1415926
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
class EdgeDetector {
private:
// original image
cv::Mat img;
// 16-bit signed int image
cv::Mat sobel;
// Aperture size of the Sobel kernel
int aperture;
// Sobel magnitude
cv::Mat sobelMagnitude;
// Sobel orientation
cv::Mat sobelOrientation;
public:
EdgeDetector() : aperture(3) {}
// Set the aperture size of the kernel
void setAperture(int a) {
aperture = a;
}
// Get the aperture size of the kernel
int getAperture() const {
return aperture;
}
// Compute the Sobel
void computeSobel(const cv::Mat& image) {
cv::Mat sobelX;
cv::Mat sobelY;
// Compute Sobel
cv::Sobel(image, sobelX, CV_32F, 1, 0, aperture);
cv::Sobel(image, sobelY, CV_32F, 0, 1, aperture);
// Compute magnitude and orientation
cv::cartToPolar(sobelX, sobelY, sobelMagnitude, sobelOrientation);
}
// Compute the Sobel
void computeSobel(const cv::Mat& image, cv::Mat &sobelX, cv::Mat &sobelY) {
// Compute Sobel
cv::Sobel(image, sobelX, CV_32F, 1, 0, aperture);
cv::Sobel(image, sobelY, CV_32F, 0, 1, aperture);
// Compute magnitude and orientation
cv::cartToPolar(sobelX, sobelY, sobelMagnitude, sobelOrientation);
}
// Get Sobel magnitude
cv::Mat getMagnitude() {
return sobelMagnitude;
}
// Get Sobel orientation
cv::Mat getOrientation() {
return sobelOrientation;
}
// Get a thresholded binary map
cv::Mat getBinaryMap(double threshold) {
cv::Mat bin;
cv::threshold(sobelMagnitude, bin, threshold, 255, cv::THRESH_BINARY_INV);
return bin;
}
// Get a CV_8U image of the Sobel
cv::Mat getSobelImage() {
cv::Mat bin;
double minval, maxval;
cv::minMaxLoc(sobelMagnitude, &minval, &maxval);
sobelMagnitude.convertTo(bin, CV_8U, 255 / maxval);
return bin;
}
// Get a CV_8U image of the Sobel orientation
// 1 gray-level = 2 degrees
cv::Mat getSobelOrientationImage() {
cv::Mat bin;
sobelOrientation.convertTo(bin, CV_8U, 90 / PI);
return bin;
}
};
#endif
#include <iostream>
#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include "edgedetector.h"
#define PI 3.1415926
int main()
{
// Read input image
cv::Mat image = cv::imread("E:\\OpenCV\\OpenCV3源码\\images\\road.jpg", 0);
if (!image.data)
return 0;
// Display the image
cv::namedWindow("Original Image");
cv::imshow("Original Image", image);
// Compute Sobel
EdgeDetector ed;
ed.computeSobel(image);
// Display the Sobel orientation
cv::namedWindow("Sobel (orientation)");
cv::imshow("Sobel (orientation)", ed.getSobelOrientationImage());
//cv::imwrite("ori.bmp", ed.getSobelOrientationImage());
// Display the Sobel low threshold
cv::namedWindow("Sobel (low threshold)");
cv::imshow("Sobel (low threshold)", ed.getBinaryMap(125));
// Display the Sobel high threshold
cv::namedWindow("Sobel (high threshold)");
cv::imshow("Sobel (high threshold)", ed.getBinaryMap(350));
结果:
使用canny算子:
// Apply Canny algorithm
cv::Mat contours;
cv::Canny(image, contours, 125, 350);
// Display the image of contours
cv::namedWindow("Canny Contours");
cv::imshow("Canny Contours",255-contours);
结果: