数字图像处理(c++ opencv):图像分割-基本边缘检测

news/2024/11/18 17:17:15/

Kirsch边缘检测

Kirsch边缘检测利用8个方向的核对图像进行检测,使每个像素点的结果为八个方向中响应最大的值。

Kirsch核:
在这里插入图片描述

#include<iostream>
#include<opencv2/opencv.hpp>
#include<algorithm>using namespace cv;
using namespace std;int main()
{Mat image, image_gray, image_bw, image_bw1, image_bw2, image_bw3;Mat image_bw4, image_bw5, image_bw6, image_bw7, image_bw8;image = imread("lena.png");  //读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}//转换为灰度图像cvtColor(image, image_gray, COLOR_BGR2GRAY);cv::imshow("image_gray", image_gray);//构建检测核Mat kernel1 = (cv::Mat_<float>(3, 3) << -3, -3, 5, -3, 0, 5, -3, -3, 5);//NMat kernel2 = (cv::Mat_<float>(3, 3) << -3, 5, 5, -3, 0, 5, -3, -3, -3);//NWMat kernel3 = (cv::Mat_<float>(3, 3) << 5, 5, 5, -3, 0, -3, -3, -3, -3);//WMat kernel4 = (cv::Mat_<float>(3, 3) << 5, 5, -3, 5, 0, -3, -3, -3, -3);//SWMat kernel5 = (cv::Mat_<float>(3, 3) << 5, -3, -3, 5, 0, -3, 5, -3, -3);//SMat kernel6 = (cv::Mat_<float>(3, 3) << -3, -3, -3, 5, 0, -3, 5, 5, -3);//SEMat kernel7 = (cv::Mat_<float>(3, 3) << -3, -3, -3, -3, 0, -3, 5, 5, 5);//EMat kernel8 = (cv::Mat_<float>(3, 3) << -3, -3, -3, -3, 0, 5, -3, 5, 5);//NE//利用filter2D进行处理filter2D(image_gray, image_bw1, -1, kernel1);filter2D(image_gray, image_bw2, -1, kernel2);filter2D(image_gray, image_bw3, -1, kernel3);filter2D(image_gray, image_bw4, -1, kernel4);filter2D(image_gray, image_bw5, -1, kernel5);filter2D(image_gray, image_bw6, -1, kernel6);filter2D(image_gray, image_bw7, -1, kernel7);filter2D(image_gray, image_bw8, -1, kernel8);//绝对值convertScaleAbs(image_bw1, image_bw1);convertScaleAbs(image_bw2, image_bw2);convertScaleAbs(image_bw3, image_bw3);convertScaleAbs(image_bw4, image_bw4);convertScaleAbs(image_bw5, image_bw5);convertScaleAbs(image_bw6, image_bw6);convertScaleAbs(image_bw7, image_bw7);convertScaleAbs(image_bw8, image_bw8);image_bw = image_gray.clone();for (int i = 0; i < image_gray.rows; i++){for (int j = 0; j < image_gray.cols; j++){int arr[] = {image_bw1.at<uchar>(i, j), image_bw2.at<uchar>(i, j), image_bw3.at<uchar>(i, j), image_bw4.at<uchar>(i, j), image_bw5.at<uchar>(i, j), image_bw6.at<uchar>(i, j), image_bw7.at<uchar>(i, j), image_bw8.at<uchar>(i, j)};int max_num = *max_element(arr, arr + 8);image_bw.at<uchar>(i, j) = max_num;}}threshold(image_bw, image_bw, 220, 255, 0);cv::imshow("image_bw", image_bw);cv::waitKey(0);  //暂停,保持图像显示,等待按键结束return 0;
}

在这里插入图片描述

log边缘检测

log边缘检测(Marr-Hildreth边缘检测)

来源

Marr和Hildreth在研究图像边缘时,认为:

  • (a)灰度变化与图像尺度是相关的,即不同图像对应不同大小的算子;

  • (b)边缘(灰度值突变处)在一阶导数中表现为峰值或谷值,在二阶导数中表现为过零点。

因此认为边缘检测算子应该有以下特征

  • (a)是一个微分算子,能够计算图像中每个点的一阶或二阶导数;

  • (b)尺度能够调节,以便尺度较大的算子能够检测模糊边缘(模糊的边缘宽度较大),小算子检测清晰边缘。

数学原理

Marr和Hildreth认为满足上面特征的最好算子的函数为:高斯拉普拉斯(LOG)函数
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f3b45f403462413b9754f53e110c339f.png
来看看这个LOG函数怎么来的:

首先介绍一下用到的拉普拉斯算子高斯函数(均为二维空间中的表达)

拉普拉斯算子:拉普拉斯算子或是拉普拉斯算符(英语:Laplace operator, Laplacian)是由欧几里得空间中的一个函数的梯度的散度给出的微分算子,通常写成 在这里插入图片描述 ,也就是log算子的前半部分。有:
在这里插入图片描述
高斯:二维高斯分布常用于图像的卷积滤波,通过该分布可以取不同尺度的高斯核。G(x, y)也就是LOG函数后半部分,有在这里插入图片描述
在这里插入图片描述
根据上面两个的公式或定义,拉普拉斯可以计算图像的二阶导数,高斯可以构建不同尺度的算子,满足上面对算子的两个要求。LOG函数有:在这里插入图片描述
然后将高斯公式代入,推到得到最终的高斯拉普拉斯(LOG)函数表达式:
在这里插入图片描述
在这里插入图片描述

数字图像中的LOG检测算子核的构建

有两种方法构建检测核:

一是直接由LOG函数进行计算取核;(取样后还要标定系数使系数和为零)

二是首先构建高斯核,然后用拉普拉斯核进行卷积得到LOG核

拉普拉斯核:
在这里插入图片描述
由于拉普拉斯与高斯是线性计算,上面两种核的构建也就表示了使用LOG对图像进行边缘检测时有两种方法:

  • 一是直接用LOG核对图像进行卷积:
    在这里插入图片描述

  • 二是先对图像进行高斯滤波,再对滤波后的图像进行拉普拉斯变换:
    在这里插入图片描述

#include<opencv2/opencv.hpp>using namespace std;
using namespace cv;void LOG1(Mat image_input, Mat image_output);
void LOG2(Mat image_input, Mat image_output);int main()
{Mat img1 = imread("lena.png", 0);//读取灰度图像if (img1.empty()){cout << "读取错误" << endl;return -1;}imshow("img1", img1);Mat img2 = Mat(img1.size(), CV_8U, Scalar(0));Mat img3 = Mat(img1.size(), CV_8U, Scalar(0));LOG1(img1, img2);//LOG边缘检测imshow("img2", img2);LOG2(img1, img3);//LOG边缘检测imshow("img3", img3);waitKey();return 0;
}void LOG1(Mat image_input, Mat image_output)
{Mat temp = Mat(image_input.size(), CV_64F, Scalar(0));//1、构建LOG算子Mat log_kernel = (cv::Mat_<float>(5, 5) << 0, 0, -1, 0, 0,0, -1, -2, -1, 0,-1, -2, 16, -2, -1,0, -1, -2, -1, 0,0, 0, -1, 0, 0);//LOG的5*5大小的核//2、卷积运算filter2D(image_input, image_output, -1, log_kernel);}void LOG2(Mat image_input, Mat image_output)
{GaussianBlur(image_input, image_output, Size(5, 5), 1, 1);Laplacian(image_output, image_output, image_input.depth(), 3, 1, 0, BORDER_DEFAULT);}

在这里插入图片描述


http://www.ppmy.cn/news/1548041.html

相关文章

C/C++基础知识复习(23)

) 什么是 C 内联函数&#xff1f;它的作用是什么&#xff1f; C 内联函数&#xff08;inline function&#xff09; 是一种通过编译器优化的特殊函数。内联函数的主要作用是减少函数调用的开销&#xff0c;使得程序执行更加高效&#xff0c;尤其是对于那些频繁调用的函数。 当…

maven 中存在jar包,但是pom无法依赖

这篇文章&#xff0c;记录了部分问题 ​​​​​​​快速全方位解决&#xff1a;maven仓库里有jar包但是pom文件中依赖不到 报错~_maven仓库中有jar包但是引用不到-CSDN博客 主要还是jar包的pom文件命名问题&#xff0c;xx.pom.lastUpdate 其中多了lastUpdate&#xff0c;去掉…

计算机网络 第二章:物理层

一、 基本概念 1.1 物理层作用、要解决的问题 第一章提到过&#xff0c;物理层要解决的问题是&#xff1a;用什么信号传输比特0和1&#xff1f; 现在的计算机网络有很多传输媒体&#xff0c;物理层的作用就是尽可能的屏蔽掉这些传输媒体的差异&#xff0c;这样就能更好地为数…

hbase未来的发展趋势

HBase 作为一个开源的分布式、可伸缩的 NoSQL 数据库,依托于 Hadoop 生态系统,以处理海量结构化数据为优势。随着大数据技术的发展,HBase 的发展趋势主要体现在以下几个方面: 1. 与云计算深度集成 随着企业向云迁移,HBase 也正在越来越多地部署在云环境中。云服务商(如 …

康威定律和数据中心网络

异想天开无罪&#xff0c;为啥不能再激进一点&#xff0c;但异想天开罪不可恕啊。 本文讲的就是数据中心网络&#xff0c;广域网不算&#xff0c;广域网还是要遵循分层&#xff0c;解耦&#xff0c;胖端瘦网原则&#xff0c;但数据中心不是&#xff0c;数据中心经理说了算。 …

企业如何提高招聘能力?

企业如何提高招聘能力&#xff1f; 许多企业在进行招聘工作时&#xff0c;常常会遇到各种问题和挑战。尽管付出了大量的时间和精力&#xff0c;但结果却并不总是如人意。例如&#xff0c;企业可能会经历一次又一次的面试&#xff0c;却仍然找不到一个能够适应岗位要求的合适人…

nginx源码安装配置ssl域名

nginx源码安装 下载 wget http://nginx.org/download/nginx-1.24.0.tar.gz 解压 tar -zxvf nginx-1.24.0.tar.gz 下载openssl apt install openssl 安装nginx cd nginx-1.24.0 sudo apt-get install libpcre3 libpcre3-dev ./configure --prefix=/home/nginx24 --with-http_ss…

Ceph的pool有两种类型

Replicated Pool&#xff08;拷贝型Pool&#xff0c;默认&#xff09; 概述&#xff1a; 这是Ceph的默认存储池类型。它通过生成对象的多份拷贝来确保数据的冗余和高可用性。 工作原理&#xff1a; 每个存入的对象&#xff08;Object&#xff09;都会被存储为多个副本&#xf…