Skip to content

Commit 8bd497f

Browse files
committed
Update Sobel Edge Detection.cpp
1 parent 3ca1c34 commit 8bd497f

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

Feature Extraction/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Opencv和C++实现图像特征提取的一些算法
2+
3+
- Sobel Edge Detection.cpp C++实现了OpenCV中的Sobel边缘检测算法。算法原理请看:https://blog.csdn.net/just_sort/article/details/85015054
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include "opencv2/opencv.hpp"
2+
#include "iostream"
3+
#include "algorithm"
4+
#include "vector"
5+
#include "stdio.h"
6+
using namespace std;
7+
using namespace cv;
8+
9+
const int fac[9]={1, 1, 2, 6, 24, 120, 720, 5040, 40320};
10+
//Sobel平滑算子
11+
Mat getSmmoothKernel(int ksize){
12+
Mat Smooth = Mat::zeros(Size(ksize, 1), CV_32FC1);
13+
for(int i = 0; i < ksize; i++){
14+
Smooth.at<float>(0, i) = float(fac[ksize-1]/(fac[i] * fac[ksize-1-i]));
15+
}
16+
return Smooth;
17+
}
18+
//Sobel差分算子
19+
Mat getDiffKernel(int ksize){
20+
Mat Diff = Mat::zeros(Size(ksize, 1), CV_32FC1);
21+
Mat preDiff = getSmmoothKernel(ksize-1);
22+
for(int i = 0; i < ksize; i++){
23+
if(i == 0){
24+
Diff.at<float>(0, i) = 1;
25+
}else if(i == ksize-1){
26+
Diff.at<float>(0, i) = -1;
27+
}else{
28+
Diff.at<float>(0, i) = preDiff.at<float>(0, i) - preDiff.at<float>(0, i-1);
29+
}
30+
}
31+
return Diff;
32+
}
33+
//调用filter2D实现卷积
34+
void conv2D(InputArray src, InputArray kernel, OutputArray dst, int dep, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT){
35+
Mat kernelFlip;
36+
flip(kernel, kernelFlip, -1);
37+
filter2D(src, dst, dep, kernelFlip, anchor, 0.0, borderType);
38+
}
39+
//先进行垂直方向的卷积,再进行水平方向的卷积
40+
void sepConv2D_Y_X(InputArray src, OutputArray dst, int dep, InputArray kernelY, InputArray kernelX, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT){
41+
Mat Y;
42+
conv2D(src, kernelY, Y, dep, anchor, borderType);
43+
conv2D(Y, kernelX, dst, dep, anchor, borderType);
44+
}
45+
//先进行水平方向的卷积,再进行垂直方向的卷积
46+
void sepConv2D_X_Y(InputArray src, OutputArray dst, int dep, InputArray kernelX, InputArray kernelY, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT){
47+
Mat X;
48+
conv2D(src, kernelX, X, dep, anchor, borderType);
49+
conv2D(X, kernelY, dst, dep, anchor, borderType);
50+
}
51+
//Sobel算子提取边缘信息
52+
Mat Sobel(Mat &src, int x_flag, int y_flag, int kSize, int borderType){
53+
Mat Smooth = getSmmoothKernel(kSize);
54+
Mat Diff = getDiffKernel(kSize);
55+
Mat dst;
56+
if(x_flag){
57+
sepConv2D_Y_X(src, dst, CV_32FC1, Smooth.t(), Diff, Point(-1, -1), borderType);
58+
}else if(x_flag == 0 && y_flag){
59+
sepConv2D_X_Y(src, dst, CV_32FC1, Smooth, Diff.t(), Point(-1, -1), borderType);
60+
}
61+
return dst;
62+
}
63+
int main(){
64+
Mat src = imread("../lena.jpg");
65+
Mat gray;
66+
cvtColor(src, gray, CV_BGR2GRAY);
67+
Mat dst1 = Sobel(gray, 1, 0, 3, BORDER_DEFAULT);
68+
Mat dst2 = Sobel(gray, 0, 1, 3, BORDER_DEFAULT);
69+
//转8位灰度图显示
70+
convertScaleAbs(dst1, dst1);
71+
convertScaleAbs(dst2, dst2);
72+
imshow("origin", gray);
73+
imshow("result-X", dst1);
74+
imshow("result-Y", dst2);
75+
imwrite("../result.jpg", dst1);
76+
imwrite("../result2.jpg", dst2);
77+
waitKey(0);
78+
return 0;
79+
}

0 commit comments

Comments
 (0)