#include "cv.h"
#include <math.h>
#include <cmath>
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
const float PI = 3.14159;
void nonMaximumSuppression(Mat &mag, Mat &gau);
void traceEdges(int x, int y, Mat &mag, int up, int low, Mat &result);
void CannyED(Mat &img, Mat &result, int up, int low);
void edgeDetection(Mat &mag, int up, int low, Mat &result);
int main()
{
Mat img = imread("origin.png", 0);
int upThrehold = 200;
int lowThrehold = 100;
Mat result;
CannyED(img, result, upThrehold, lowThrehold);
imshow("origin", img);
imshow("result", result);
imwrite("result.png", result);
waitKey();
return 0;
}
void traceEdges(int x, int y, Mat &mag, int up, int low, Mat &result)
{
result.at<float>(y, x) = 255;
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
if((i != 0) && (j != 0) && (x + i >= 0) && (y + j >= 0) && (x + i <= mag.cols-1) && (y + j <= mag.rows-1)){
if((mag.at<float>(y + j, x + i) > low) && (result.at<float>(y + j, x + i) != 255)) {
traceEdges(x + i, y + j, mag, up, low, result);
}
}
}
}
}
void edgeDetection(Mat &mag, int up, int low, Mat &result)
{
int rows = mag.rows;
int cols = mag.cols;
result = Mat(mag.size(), CV_32F, 0.0);
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
if (mag.at<float>(y, x) >= up){
traceEdges(x, y, mag, up, low, result);
}
}
}
}
void nonMaximumSuppression(Mat &mag, Mat &gau)
{
Mat check = Mat(mag.rows, mag.cols, CV_8U);
MatIterator_<float>itMag = mag.begin<float>();
MatIterator_<float>itGau= gau.begin<float>();
MatIterator_<float>itMagEnd = mag.end<float>();
MatIterator_<unsigned char>itCheck = check.begin<unsigned char>();
while(itMag != itMagEnd) {
const Point pos = itCheck.pos();
float dir = atan(*itGau) * (180 / PI);
while(dir < 0) dir += 180;
*itGau = dir;
if (dir > 22.5 && dir <= 67.5) {
//如果当前像素点不是梯度方向最大点,将其设为0(背景色)
if(pos.y > 0 && pos.x > 0 && *itMag <= mag.at<float>(pos.y - 1, pos.x - 1)) {
mag.at<float>(pos.y, pos.x) = 0;
}
if(pos.y < mag.rows-1 && pos.x < mag.cols-1 && *itMag <= mag.at<float>(pos.y + 1, pos.x + 1)) {
mag.at<float>(pos.y, pos.x) = 0;
}
} else if(dir > 67.5 && dir <= 112.5) {
if(pos.y > 0 && *itMag <= mag.at<float>(pos.y-1, pos.x)) {
mag.at<float>(pos.y, pos.x) = 0;
}
if(pos.y<mag.rows-1 && *itMag<=mag.at<float>(pos.y+1, pos.x)) {
mag.at<float>(pos.y, pos.x) = 0;
}
} else if(dir > 112.5 && dir <= 157.5) {
if(pos.y>0 && pos.x<mag.cols-1 && *itMag<=mag.at<float>(pos.y-1, pos.x+1)) {
mag.at<float>(pos.y, pos.x) = 0;;
}
if(pos.y < mag.rows-1 && pos.x>0 && *itMag<=mag.at<float>(pos.y+1, pos.x-1)) {
mag.at<float>(pos.y, pos.x) = 0;
}
} else {
if(pos.x > 0 && *itMag <= mag.at<float>(pos.y, pos.x-1)) {
mag.at<float>(pos.y, pos.x) = 0;
}
if(pos.x < mag.cols-1 && *itMag <= mag.at<float>(pos.y, pos.x+1)) {
mag.at<float>(pos.y, pos.x) = 0;
}
}
++itGau;
++itCheck;
++itMag;
}
}
void CannyED(Mat &img, Mat &result, int up, int low)
{
Mat img2 = img.clone();
//高斯模糊
GaussianBlur(img, img2, Size(3, 3), 1);
//用Sobel算子计算梯度幅值和方向
Mat Gx = Mat(img.rows, img.cols, CV_32F);
Mat Gy = Mat(img.rows, img.cols, CV_32F);
Sobel(img2, Gx, CV_32F, 1, 0, 3);
Sobel(img2, Gy, CV_32F, 0, 1, 3);
Mat gau = Mat(img2.rows, img2.cols, CV_32F);
//slopes = gy/gx
divide(Gy, Gx, gau);
//sum = gx^2 + gy^2
Mat sum = Mat(img2.rows, img2.cols, CV_64F);
Mat x2 = Mat(img2.rows, img2.cols, CV_64F);
Mat y2 = Mat(img2.rows, img2.cols, CV_64F);
multiply(Gx, Gx, x2);
multiply(Gy, Gy, y2);
sum = x2 + y2;
//sum = 根号sum
sqrt(sum, sum);
Mat magnitude = sum.clone();
//非极大值抑制
nonMaximumSuppression(magnitude, gau);
//边缘检测
edgeDetection(magnitude, up, low, result);
}
使用canny算法进行图像边缘检测
4星 · 超过85%的资源 需积分: 35 176 浏览量
2016-01-08
08:44:33
上传
评论 2
收藏 1KB RAR 举报
倾心软件
- 粉丝: 27
- 资源: 87
最新资源
- 记录了贪心,动态规划等算法基本思想与设计.zip
- 基于菲阿里基本模型,以及MACD RSI BooL 等技术指标 构建一套基于贪心算法策略的智能投顾模型.zip
- oj算法代码-贪心算法.zip
- 基于yolov8行人检测源码+模型.zip
- 公开整理-地级市-绿色专利申请、授权数据集(2000-2022年).xlsx
- 基于Transformer模型的图像质量评分模型实现源码+详细说明文档.zip
- CST电磁场仿真+线性螺旋电感+建模步骤细节和RLC端口配置+CST高级建模操作
- 大数据库实验的报告材料材料(word文档良心出品).doc
- AIS2024 valid
- 最入门的爬虫代码 python.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈